【问题标题】:Get the length of a SVG line,rect,polygon and circle tags获取 SVG 线条、矩形、多边形和圆形标签的长度
【发布时间】:2015-05-20 16:20:17
【问题描述】:

我设法找到了 svg 中路径的长度,但现在我想从 SVG 中找到直线、矩形、多边形和圆形标签的长度,我现在真的迷路了,还有线索吗?还是已经有一些类似路径的功能?

【问题讨论】:

  • 我想做的是为它们中的每一个添加 dasharray 和 dashoffset,但我需要确切的长度以使它们不可见,我想制作绘图效果,但也适用于这些标签跨度>
  • 我可以使用inkscape将它们全部转换为路径,但这只是一种解决方法,如果可能的话我想这样做

标签: javascript jquery html svg


【解决方案1】:

如果其他人想找到这些标签的长度,我为每个标签制作了一些功能,测试了它们,我说它们工作得很好,这就是我需要的。

var tools = {


            /**
             *
             * Used to get the length of a rect
             *
             * @param el is the rect element ex $('.rect')
             * @return the length of the rect in px
             */
            getRectLength:function(el){
                var w = el.attr('width');
                var h = el.attr('height');

                return (w*2)+(h*2);
            },

            /**
             *
             * Used to get the length of a Polygon
             *
             * @param el is the Polygon element ex $('.polygon')
             * @return the length of the Polygon in px
             */
            getPolygonLength:function(el){
                var points = el.attr('points');
                points = points.split(" ");
                var x1 = null, x2, y1 = null, y2 , lineLength = 0, x3, y3;
                for(var i = 0; i < points.length; i++){
                    var coords = points[i].split(",");
                    if(x1 == null && y1 == null){

                        if(/(\r\n|\n|\r)/gm.test(coords[0])){
                            coords[0] = coords[0].replace(/(\r\n|\n|\r)/gm,"");
                            coords[0] = coords[0].replace(/\s+/g,"");
                        }

                        if(/(\r\n|\n|\r)/gm.test(coords[1])){
                            coords[0] = coords[1].replace(/(\r\n|\n|\r)/gm,"");
                            coords[0] = coords[1].replace(/\s+/g,"");
                        }

                        x1 = coords[0];
                        y1 = coords[1];
                        x3 = coords[0];
                        y3 = coords[1];

                    }else{

                        if(coords[0] != "" && coords[1] != ""){             

                            if(/(\r\n|\n|\r)/gm.test(coords[0])){
                                coords[0] = coords[0].replace(/(\r\n|\n|\r)/gm,"");
                                coords[0] = coords[0].replace(/\s+/g,"");
                            }

                            if(/(\r\n|\n|\r)/gm.test(coords[1])){
                                coords[0] = coords[1].replace(/(\r\n|\n|\r)/gm,"");
                                coords[0] = coords[1].replace(/\s+/g,"");
                            }

                            x2 = coords[0];
                            y2 = coords[1];

                            lineLength += Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));

                            x1 = x2;
                            y1 = y2;
                            if(i == points.length-2){
                                lineLength += Math.sqrt(Math.pow((x3-x1), 2)+Math.pow((y3-y1),2));
                            }

                        }
                    }

                }
                return lineLength;

            },

            /**
             *
             * Used to get the length of a line
             *
             * @param el is the line element ex $('.line')
             * @return the length of the line in px
             */
            getLineLength:function(el){
                var x1 = el.attr('x1');
                var x2 = el.attr('x2');
                var y1 = el.attr('y1');
                var y2 = el.attr('y2');
                var lineLength = Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2));
                return lineLength;

            },

            /**
             *
             * Used to get the length of a circle
             *
             * @param el is the circle element
             * @return the length of the circle in px
             */
            getCircleLength:function(el){
                var r = el.attr('r');
                var circleLength = 2 * Math.PI * r; 
                return circleLength;
            },


            /**
             *
             * Used to get the length of the path
             *
             * @param el is the path element
             * @return the length of the path in px
             */
            getPathLength:function(el){
                var pathCoords = el.get(0);
                var pathLength = pathCoords.getTotalLength();
                return pathLength;
            }
        }

【讨论】:

  • 为了让生活更轻松,我创建了一个简单的插件来动画 svg 笔画,github.com/Zet-Tools/zPath.js
  • 感谢您的代码,我在我的 SVG 插件中使用它来允许其他 SVG 元素的描边动画。惊人的! thednp.github.io/kute.js/svg.html#draw-example
  • 不错!如果您要使用 el.getAttribute() 更改 el.attr() jQuery 函数,这适用于 vanilla JavaScript ;) 并且对于路径,您只需要返回 el.getTotalLength() 本机函数 ;)
【解决方案2】:

我认为您对问题的看法不正确:

rectangle = 2 * (width + height)的长度

线的长度(对于任何非垂直线 c^2 = a^2 + b^2 使用勾股定理)或对于水平使用(x1 到 x2),对于垂直使用(y1 到 y2)

圆的长度 = 2 × π × 半径 ...等

【讨论】:

  • 天哪,你是对的,我没有想到这个,它是如此简单......谢谢你
【解决方案3】:

在 SVG 2 中,所有几何元素都将具有 pathLength 属性,但截至 2017 年 5 月,这仍将在大多数浏览器中实现。

请参阅https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement 了解更多信息。

我们可以在未来证明@zetcoby 的答案:

if( el.pathLength ) {
   return el.pathLength;
}
else {
    // rest of code...
}

【讨论】:

    【解决方案4】:

    我尝试将 ZetCoby 指定的答案用于多边形,但在测试中我发现它返回的路径长度是错误的。

    例子:

    <polygon points="10.524,10.524 10.524,24.525 24.525,24.525 24.525,10.524" style="fill:none;stroke-width:0.2;stroke:black"></polygon>
    

    上述多边形的长度应该是56,但getPolygonLength(el)函数返回的值是61.79898987322332

    我编写了一个算法来正确计算 SVG 多边形的路径长度,所以我认为我应该将其提供回来,因为这是在搜索此问题时谷歌上的第一次点击。

    这是我的功能。享受...

    function polygon_length(el) {
      var points = el.attr('points');
      points = points.split(' ');
      if (points.length > 1) {
        function coord(c_str) {
          var c = c_str.split(',');
          if (c.length != 2) {
            return; // return undefined
          }
          if (isNaN(c[0]) || isNaN(c[1])) {
            return;
          }
          return [parseFloat(c[0]), parseFloat(c[1])];
        }
    
        function dist(c1, c2) {
          if (c1 != undefined && c2 != undefined) {
            return Math.sqrt(Math.pow((c2[0]-c1[0]), 2) + Math.pow((c2[1]-c1[1]), 2));
          } else {
            return 0;
          }
        }
    
        var len = 0;
        // measure polygon
        if (points.length > 2) {
          for (var i=0; i<points.length-1; i++) {
            len += dist(coord(points[i]), coord(points[i+1]));
          }
        }
        // measure line or measure polygon close line
        len += dist(coord(points[0]), coord(points[points.length-1]));
        return len;
      } else {
        return 0;
      }
    }
    

    【讨论】:

    • 谢谢@swill,我会仔细检查所有方法以确保它返回正确的长度,如果你没问题,我想在我的插件中使用你的解决方案。
    • 随意使用我的解决方案。感谢您投入工作以尝试为他人解决此问题。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2015-09-22
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多