SVG getTotalLength()不会为非缩放笔划返回正确的大小 - 获取SVG比例

时间:2017-06-06 12:11:04

标签: javascript css svg responsive

我使用javascript获取路径长度并将其中一半应用于stroke-DashArray。我的问题是我使用vector-effect="non-scaling-stroke"所以没有规模,它总是保持stroke-width:2px;非缩放似乎影响笔画属性的每个部分,包括DashArray所以我需要得到比例svg然后缩放path.getTotalLength();

有没有办法使用javascript来获取SVG计算比例作为路径长度的乘数?

我做了codepen.io来证明这个问题。只需调整视口大小即可查看笔划更改。

3 个答案:

答案 0 :(得分:2)

只想让更多人关注 Sam 上面的评论/答案,这对我有用!

path.getBoundingClientRect().width/path.getBBox().width 将返回一个比例数字。

然后您可以使用 path.getTotalLength() * scale;

将比例乘以路径的长度

答案 1 :(得分:0)

我认为您必须划分视框大小/ SVG宽度



  <!doctype html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head> 
  <body>
    <button onclick="dashAni(myPath, 50, 3500)">start</button>
    <svg id="mySVG"  width="200" height="200" viewBox="0 0 500 500">
        <path 
        vector-effect="non-scaling-stroke"
        id="myPath" d="M 50,250 c 0 -100   150 -100   200 0 
                                      c 50 100   200 100   200 0
                                      c -0 -100   -150 -100   -200 0
                                      c -50 100   -200 100   -200 0
                                      z" 
        stroke="#eee"
        stroke-width="5" fill="none" />
    </svg>
    <script>
      var dashAni = function(path, length, duration){
        var dashPath = path.cloneNode(true);
        mySVG.appendChild(dashPath);
        var pathLen=path.getTotalLength()/2.5;  
        var aktPos=0
        var sumSteps = duration / (1000/60) // 60 pics per second
        var step=0;
        var pathAnim;
        dashPath.setAttribute('stroke-dasharray', length + ' ' + (pathLen - length));
        dashPath.setAttribute('stroke', "red");
        dashPath.setAttribute('stroke-dashoffset', aktPos);

        var anim=function(){
           aktPos = pathLen/sumSteps*step*-1;
            //aktLen = easeInOutQuad(step/sumSteps)*len;
           dashPath.setAttribute('stroke-dasharray', length + ' ' + pathLen);
           dashPath.setAttribute('stroke-dashoffset', aktPos);

           if (step <= (sumSteps)){
            step++;
            pathAnim = setTimeout(anim, 1000/60) //1000/60 pics/second
            } else {
              mySVG.removeChild(dashPath);
              clearTimeout(pathAnim);
            }
        }
       anim();
      }
    </script>
  </body>
  </html>
  
&#13;
&#13;
&#13;

答案 2 :(得分:0)

对于现在正在为此苦苦挣扎的任何人,上面建议的缩放解决方案对我不起作用,我认为这是因为我没有按比例调整 svg 的大小(它设置为填充浏览器窗口)。不过,我为我的用例发现了一个简单的解决方案,即 boundingClientRect 和勾股定理:

let boundingClient=el.getBoundingClientRect();
let pathLength=Math.sqrt(boundingClient.width**2 + boundingClient.height**2);

这对我来说非常合适,只要窗口调整大小就需要重新计算。