Javascript的getBBox()提供了一个比其内容文本高的框。为什么?

Saq*_*Ali 1 javascript svg d3.js

我正在使用D3.js在SVG容器上绘制一些文本(“ 100%”)。

现在,我试图找出该文本周围的边框的尺寸。

这是我的方法:

      var label = svgContainer.append("text")
        .attr("x", 200)
        .attr("y", 200)
        .text("100%")
        .attr("font-family", "Courier New")
        .attr("font-weight", "bold")
        .attr("font-size", "10px")
        .attr("fill", "black");
        .attr("transform", function(d){
            var bb = this.getBBox();
            console.log("bb.width = ", bb.width);
            console.log("bb.height = ", bb.height);
            return "translate(0, 0)";
          }
        );
Run Code Online (Sandbox Code Playgroud)

这不仅会在屏幕上绘制字符串“ 100%”,而且还会在console.log中输出边框的宽度和高度(分别为24和11.5!);

现在,我想在屏幕上可视化上述边界框。因此,在上面的代码之前,我会添加以下代码:

        var rect = svgContainer.append("rect")
          .attr("x", 200)
          .attr("y", 200-11.5)
          .attr("width", 24)
          .attr("height", 11.5)
          .attr("fill", "pink");
Run Code Online (Sandbox Code Playgroud)

当我运行更改后的代码时,我期望在“ 100%”字符串周围看到一个粉红色的边框。但是我看到了以下内容!

在此处输入图片说明

为什么粉红色边框比文字高?我需要获取文本实际边框的尺寸-不能比其高。我怎么做?

这是Plunker:https://plnkr.co/edit/XoVSZwTBNXhdKKJKkYWn

Pau*_*eau 5

这里有两件事:

  1. 您仅使用边界框的高度和宽度字段。您还应该考虑边界框的x和y属性-正如@Gilsha正确指出的那样。当您确实调整了x和y时,您会看到该框位于下方:

var svg = document.getElementById("my_svg_widget");

    
var bbox = svg.getElementById("test").getBBox();

var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", bbox.x);
rect.setAttribute("y", bbox.y);
rect.setAttribute("width", bbox.width);
rect.setAttribute("height", bbox.height);
rect.setAttribute("fill", "rgba(255, 0, 0, 0.5)");
svg.appendChild(rect);
Run Code Online (Sandbox Code Playgroud)
<svg id="my_svg_widget" width="300" height="300" style="border-style:solid;border-color:purple;border-width: 2px;">
  <text id="test" x="100" y="100" font-family="Courier New" font-weight="bold" font-size="50px">100%</text>
</svg>
Run Code Online (Sandbox Code Playgroud)

  1. 这带给我们第二个原因。返回的边界框getBBox()不是字形周围的紧密边界框。它包括文本的整个em-box高度-包括升序(字体中最高的字符)和降序(最低于基线以下)的余量。

如果我们在文本元素中包含某些字符,您会明白我的意思。

var svg = document.getElementById("my_svg_widget");

    
var bbox = svg.getElementById("test").getBBox();

var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", bbox.x);
rect.setAttribute("y", bbox.y);
rect.setAttribute("width", bbox.width);
rect.setAttribute("height", bbox.height);
rect.setAttribute("fill", "rgba(255, 0, 0, 0.5)");
svg.appendChild(rect);
Run Code Online (Sandbox Code Playgroud)
<svg id="my_svg_widget" width="300" height="300" style="border-style:solid;border-color:purple;border-width: 2px;">
  <text id="test" x="100" y="100" font-family="Courier New" font-weight="bold" font-size="50px">&#193;100%&#x2563;</text>
</svg>
Run Code Online (Sandbox Code Playgroud)

  • @SaqibAli在SVG中没有机制可以做到这一点。保罗向您展示的是您所能做到的。 (2认同)