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

tquggr8v  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(175)

我正在尝试使用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上获取边界框?

vhipe2zx

vhipe2zx1#

我无法让getBBox()(或互联网上任何其他建议的方法)处理文本元素,所以我进入Chrome并构建了一个字符宽度查找表,然后console.将其登录到控制台,以便我可以将其复制到我的代码中,并使用它来查找文本中的字符。它很难看,而且没有考虑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 -击中键盘上的每个字符一次,退格键后,每个所以你只测量一个字符,然后回去做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;
                        }
                    }
                }

这个解决方案让我有点抓狂,但它在字体大小不变的情况下是有效的,而且它们在两个浏览器中的大小大致相同。

相关问题