繁体   English   中英

如何获取 Firefox 上 SVG 文本节点的边界框?

[英]How do I get the bounding box of a SVG text node on Firefox?

我正在尝试使用 d3 v4 为我的 SVG 元素添加背景色。 为了做到这一点,我想我必须参考

text.node().getBBox()

所以我尝试了下面...

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    ...

  focus.append("circle")
      .attr("r", 4.5);

  var text = focus.append("text")
      .attr("x", 9)
      .attr("dy", ".35em");
  alert(text);
  var svgrect = text.node().getBBox();
  alert(svgrect);
  var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect.setAttribute("x", svgrect.x);
    rect.setAttribute("y", svgrect.y);
    rect.setAttribute("width", svgrect.width);
    rect.setAttribute("height", svgrect.height);
    rect.setAttribute("fill", "yellow");
  svg.node().insertBefore(rect, text);

但是虽然我看到了第一个警报,但我没有看到第二个警报。 在 Firefox 上,我收到错误

NS_ERROR_FAILURE:

没有任何进一步的信息。 如何获取 Firefox 上的边界框?

我无法使 getBBox()(或 inte.net 上建议的任何其他方法)处理文本元素,因此我进入 Chrome 并构建了一个字符宽度查找表,然后将其控制台登录到控制台,这样我就可以将它复制到我的代码中,并使用它来查找文本中的字符。 它很丑陋,并且没有考虑 css 的变化,但如果你的字体大小没有改变,它就可以工作。

我在这里为找不到其他方式获取信息的可怜人提供它。

我如何构建查找表:

var clm= {}; // this is our dictionary
document.querySelector("#txt-add-title").addEventListener("keyup", function(e) {
 var bbox = document.querySelector("#measuring-stick").getBBox();
 var width = bbox.width;
 var target = e.currentTarget;
 var ch = target.value;
 if (!clm[ch]) {
     clm[ch] = width;
 }
});

现在 - 在 CHROME 中 - 按键盘上的每个字符一次,在每个字符后退格,这样你只测量一个字符,然后返回 go 并执行 Shift 字符。 这将在您的字典中注册每个键及其长度

完成后,在开发者控制台中:

console.log(JSON.stringify(clm));

你会得到这样的东西:

{"0": 8.899147033691406, "1": 8.899147033691406, "2": 8.899147033691406, "3": 8.899147033691406, "4": 8.899147033691406,"5": 8.899147033691406, "6": 8.899147033691406, "7": 8.899147033691406, "8": 8.899147033691406, "9": 8.899147033691406, "a": 8.899147033691406, "": 0, "b": 8.899147033691406, "c": 8.181818008422852, "d": 8.899147033691406, "e": 8.899147033691406, "f": 5.454545021057129, "g": 8.899147033691406, "h": 8.899147033691406, "i": 3.5582385063171387, "j": 4.467329502105713, "k": 8.181818008422852, "l": 3.5582385063171387, "m": 13.330965042114258, "n": 8.899147033691406, "o": 8.899147033691406, "p": 8.899147033691406, "q": 8.899147033691406, "r": 5.909090518951416, "s": 8.004261016845703, "t": 4.545454502105713, "u": 8.899147033691406, "v": 8.181818008422852, "w": 12.272727012634277, "x": 8.63636302947998, "y": 8.181818008422852, "z": 8.181818008422852, "A": 11.363636016845703, "B": 10.674715995788574, "C": 11.555397033691406, "D": 11.555397033691406, "E": 10.674715995788574, "F": 9.779829025268555, "G": 12.450284004211426, "H": 11.555397033691406, "I": 4.4460225105285645, "J": 8.004261016845703, "K": 10.909090042114258, "L": 8.899147033691406, "M": 13.330965042114258, "N": 11.555397033691406, "O": 12.450284004211426, "P": 10.674715995788574, "Q": 12.450284004211426, "R": 11.818181037902832, "S": 10.674715995788574, "T": 9.779829025268555, "U": 11.555397033691406, "V": 11.363636016845703, "W": 15.106534004211426, "X": 11.363636016845703, "Y": 11.363636016845703, "Z": 9.779829025268555, "`": 5.33380651473999, "-": 5.33380651473999,"=": 9.346590995788574, "~": 9.346590995788574, "!": 4.4460225105285645, "@": 16.242897033691406, "#": 9.090909004211426, "$": 8.899147033691406, "%": 14.232954025268555, "^": 7.514204502105713, "&": 10.674715995788574, "*": 6.228693008422852, "(": 5.33380651473999, ")": 5.33380651473999, "_": 10, "+": 9.346590995788574, ",": 4.4460225105285645, "<": 9.346590995788574, ".": 4.4460225105285645, ">": 9.346590995788574, "/": 5, "?": 8.899147033691406, ":": 4.4460225105285645, ";": 4.4460225105285645,"'": 3.061079502105713, "[": 4.545454502105713, "{": 5.454545021057129, "]": 4.4460225105285645, "}": 5.348011016845703},
   

现在将其分配给一个变量,每当您需要获取该文本节点的长度时,您只需获取值并循环遍历字符即可获取长度,如下所示:

var width = 0;
 var bbox = document.querySelector("#measuring-stick").getBBox();
if (bbox && bbox.width > 0) { // chrome works, yay!
                    width = bbox.width;
                } else { // mozilla needs the hack
                    var v= <get your element text here > ;
                    if (v.length > 0) {
                        for (let vp = 0; vp < v.length; vp++) {
                            width += mozCharLenLookup[v[vp]] || 0;
                        }
                    }
                }

这个解决方案让我内心有些崩溃,但是当字体大小不变并且它们在两个浏览器中的大小大致相同时它就可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM