Javascript 确定使用@font-face设置样式的svg文本宽度的可靠方法

Javascript 确定使用@font-face设置样式的svg文本宽度的可靠方法,javascript,css,svg,d3.js,font-face,Javascript,Css,Svg,D3.js,Font Face,我在使用D3定位css web字体样式的svg文本元素时遇到了一个问题。当我第一次定位加载的文本元素时,它们将重叠 然而,当我稍后使用延迟触发或通过按钮触发的相同功能定位元素时,它们不会重叠 问题似乎出在getBBox()和getBoundingClientRect()这两种方法都没有首先返回元素的正确宽度 有没有关于如何首先获得正确宽度的想法 JS如下所示,示例如下: 完整代码如下: 在首次呈现元素并测量其宽度时,尚未下载所引用的字体。因此,此时,您将获得一个较小的宽度,稍后在加载引用的

我在使用D3定位css web字体样式的svg文本元素时遇到了一个问题。当我第一次定位加载的文本元素时,它们将重叠

然而,当我稍后使用延迟触发或通过按钮触发的相同功能定位元素时,它们不会重叠

问题似乎出在
getBBox()
getBoundingClientRect()
这两种方法都没有首先返回元素的正确宽度

有没有关于如何首先获得正确宽度的想法

JS如下所示,示例如下: 完整代码如下:


在首次呈现
元素并测量其宽度时,尚未下载所引用的字体。因此,此时,您将获得一个较小的宽度,稍后在加载引用的字体后将获得该宽度

等待浏览器的加载事件(as)是一件值得尝试的事情,但我不确定这是否适用于所有浏览器。我之前读过一篇文章,这意味着一些浏览器在遇到第一次使用(不仅仅是CSS声明)之前不会加载远程@font-face字体。但我没有这方面的经验,所以我不能肯定


这是一个有很多关于@font-face和下载时间的链接的好答案。

我还没有尝试过浏览器加载事件(我对web字体几乎一无所知),但是当我们遇到这个问题时(尽管在Chartbuilder上被黑客攻击),我们通过使用并等待。一个缺点是:文本必须出现在页面上才能被加载,所以你需要一个隐藏的跨距(或者其他什么)来使用你的字体

这是我们的代码(我们从以下位置加载字体:


附录:我不认为这真的有什么实际区别,但我们也改用了
getComputedTextLength()
没有测量边界框,只是因为它看起来更正确。参见。

完美!我担心我将不得不自己编写所有大小变化检测!@bouvard你在手机上有过问题吗?使用WebFontLoader和活动事件(在手机上),有时在将新字体分配给元素后直接计算文本大小时,这些都是错误的。
//helper function to grab transform coordinates 
function transformCoordOf(elem) {
    var separator = elem.attr("transform").indexOf(",") > -1 ? "," : " ";
    var trans = elem.attr("transform").split(separator);
    return { x: (trans[0] ? parseFloat(trans[0].split("(")[1]) : 0), y: (trans[1] ?         parseFloat(trans[1].split(")")[0] ): 0) };
}

//position the elements based on the one before it
function positionElements() {
    txts.filter(function(d,i){return i != 0}) //filter out the first element
        .attr("transform",function(d,i){
            var prev = d3.select(txts[0][i]), //use i b/c the list shifts on filter
            prevWidth = parseFloat(prev.node().getBoundingClientRect().width)
            prevCoords = transformCoordOf(prev);

            var cur = d3.select(this),
            curWidth = parseFloat(cur.node().getBoundingClientRect().width)
            curCoords = transformCoordOf(cur);

            var y = prevCoords.y,
                x = prevCoords.x + prevWidth + 10;

            return "translate("+x+","+y+")";
        })
}

var names = ["apples","oranges","bananas"]
var canvas = d3.select("#content")
    .append("svg")
    .attr("width","600px")
    .attr("height","100px");

var txts = canvas.selectAll("text").data(names)
    .enter()
    .append("text")
    .attr("transform","translate(10,50)")
    .text(function(d){return d});

positionElements()

d3.select("button").on("click",function(){positionElements()})
WebFont.load({
    monotype: {
        projectId: '65980087-55e2-40ca-85ae-729fca359467',
    },
    active: function(name) {
        $(document).ready(function() {
            ChartBuilder.start();
        });
    }
});