如何计算将SVG文本放置在视图框中的翻译,给定的Viewbox尺寸和文本样式



我试图理解svg中的 <text>定位。

说您有<svg viewBox="..."><text>...</text></svg>,其中查看框的尺寸正确以适合其(已知的)字体,字体重量和字体大小。如果不给<text>进行x="..." y="..."翻译,就不会在Viewbox中"正确地"放置:它的位置太高,右边有点。

我可以计算xy翻译值吗?如果翻译不取决于字体的特性,则可能不分析绘制的<text>,或者分析绘制的<text>(如果它取决于字体的特性)。

这是一个示例(也是JSFiddle:https://jsfiddle.net/enry/lnzxxx0jx/)。这是从草图中导出的 - 这就是为什么我无法访问X和Y翻译的计算。<svg>是红色轮廓的东西。要注意的是,这些特定的x和y翻译值需要将文本放置在视图框中,以使得如果隐藏了<svg>的溢出,则可以看到<text>的整个。

text {
    fill: #000;
    fill-rule: evenodd;
    font-weight: 700;
    font-family: Helvetica-Bold, Helvetica;
    font-size: 36px
}
/* just for demo purposes */
html {
    padding: 20px;
    background: #ccc
}
svg {
    outline: 1px solid red;
    background: #fff;
    overflow: hidden /* in case you want to play around with the translation */
}
translated
<svg viewBox="0 0 258 34" xmlns="http://www.w3.org/2000/svg">
    <text x="-2" y="26"><!-- << the question:
                                if these values weren't provided,
                                how would you calculate them? -->
        my sample text
    </text>
</svg>
not translated
<svg viewBox="0 0 258 34" xmlns="http://www.w3.org/2000/svg">
    <text><!--                  fwiw, the getBBox of the text without translation is
                                somewhere around -33 - -34, depending on the svg's actual size-->
        my sample text
    </text>
</svg>

为什么翻译值x =" -2"和y =" 26"?我尝试了各个百分比的Viewbox尺寸;字体大小的各个百分比;和将视图框与字体大小相关的分数……但无法弄清楚。

他们可能取决于kerning和引导 - 字母周围的空间。在这种情况下,我想我们直到绘制后才知道必要的翻译,这可能是字符周围的空间可以用JS/jQuery测量?如果是这样,该怎么做(我没有使用脚本分析印刷字符的经验)。FWIW(这是在讨论中提出的),未翻译的文本的GetBbox为x:0,y: - [几乎有34个,具体取决于SVG的实际大小] - 因此,Y非常接近 - (viewbox y)。因为GetBbox不需要SVG具有视图框,所以可以动态地确定视图框y…但是它似乎对翻译计算没有帮助。

还是基于查看框的一些计算?在我的实验中,翻译值取决于字体和字体大小……但是视图框也是如此,因此,您可能需要的全部内容来计算翻译。

我的猜测:Kerning对于X翻译很有意义 - 我可以想象SVG被领先的空格绊倒了,这可以解释为什么必须将其拉到左边。Y翻译的一部分将基线移至Viewbox的底部,但是鉴于必须翻译X的事实,我希望Y是基线加上一些调整…,这需要计算两个调整(也许是领先?)文本高度(上限高度 可能是升华高度 潜在的下降高度 - ["字体解剖学"插图])

您的问题令人困惑,因为我们希望您知道(比互联网上的随机陌生人)答案是什么。

我真正的问题是x =" -2",y =" 25"来自。

这就像问为什么一本书是蓝色的,或者为什么在架子的左端。它在那里,因为那是您 - 或设计SVG的任何人。

如果您已经很明显,那么SVG不是HTML。事情不会像在HTML中那样自动定位。您必须在SVG文档中指定元素的位置和大小。

如果您想知道为什么文本将其定位在哪里,请询问设计师。

我的猜测

..是,如果您使用给定的文本并制作其尺寸36px,则将其字体设置为" Proxima Nova",然后将其定位为" Proxima Nova",以便它位于页面左上角,则:

  1. 其右下角将在(241,33)
  2. 文本基线启动位置将在(-2,25)

,从而解释了您所得的文本X,Y坐标和您的Viewbox值。

但是我没有那个字体,所以我无法确定。

update

如果您需要重新放置文本内浏览器,则可以在某个初始位置和字体大小上添加文本。然后在文本元素上调用getBbox()。这将为您提供与初始文本位置相对于文本的界限。基于此,您可以计算最终位置和大小。您也可以修改视图框,以便如果需要的话,文本可以正确缩放。

// Find the text element
var mytext = document.getElementById("mytext");
// Get it's bounding box
var bbox = mytext.getBBox();
// Reposition text using the values from its bounding box
mytext.setAttribute("x", -bbox.x);
mytext.setAttribute("y", -bbox.y);
// Top left of text should now be at top-left of SVG (0,0)
// Now update the SVG viewBox so that it is fitted to the text
document.getElementById("mysvg").setAttribute("viewBox", "0 0 "+bbox.width+" "+bbox.height);
// Note that the bbox of the text is not tightly fitted to the text.  It includes the em boxes 
text {
    fill: #000;
    fill-rule: evenodd;
    font-weight: 700;
    font-family: Helvetica-Bold, Helvetica;
    font-size: 36px
}
/* just for demo purposes */
html {
    padding: 20px;
    background: #ccc
}
svg {
    outline: 1px solid red;
    background: #fff;
    overflow: hidden /* in case you want to play around with the translation */
}
<svg id="mysvg" viewBox="0 0 258 34" xmlns="http://www.w3.org/2000/svg">
    <text id="mytext" x="0" y="0">my sample text</text>
</svg>

在上面的示例中,我们正在移动文本位置。但是我们真的不需要。仅设置视图框将具有相同的结果。

// Find the text element
var mytext = document.getElementById("mytext");
// Get it's bounding box
var bbox = mytext.getBBox();
// Now update the SVG viewBox so that it is fitted to the text
document.getElementById("mysvg").setAttribute("viewBox", [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));
text {
    fill: #000;
    fill-rule: evenodd;
    font-weight: 700;
    font-family: Helvetica-Bold, Helvetica;
    font-size: 36px
}
/* just for demo purposes */
html {
    padding: 20px;
    background: #ccc
}
svg {
    outline: 1px solid red;
    background: #fff;
    overflow: hidden /* in case you want to play around with the translation */
}
<svg id="mysvg" viewBox="0 0 258 34" xmlns="http://www.w3.org/2000/svg">
    <text id="mytext" x="0" y="0">my sample text</text>
</svg>

最新更新