2017-07-13 39 views
1

我想排列在<svg>和 圍繞<text><rect>在相同的x座標中的幾個<text>如何在svg中設置文本的絕對x座標?

我指定的<text>x屬性來對齊幾個<text>和 我的<text>座標與getBBox()確定<rect> x位置。然而, getBBox().x與指定的x在某些<text>中不同,儘管<g>包括<text><rect>尚未轉化。

他們爲什麼不同? 如何設置<text>的絕對x座標(例如,在以下代碼中爲零)以及 如何獲取<text>的絕對x座標?

我在Windows 10(64位)上的Chrome 59(64位)上執行了以下代碼。

更新:

當我運行在Firefox代碼, 我得到了相同的(預期)x座標使用getBBox().x<text>x屬性。

Chrome需要額外的努力嗎?

const PADDING = 5 
 
const BOX_X = 10 
 

 
const data = [ 
 
    {text: "My"}, 
 
    {text: "x"}, 
 
    {text: "coordinate"}, 
 
    {text: "is"}, 
 
    {text: "zero?"} 
 
] 
 

 
const box = d3.select("svg#svg") 
 
    .selectAll(".text-rect") 
 
    .data(data) 
 
    .enter() 
 
    .append("g") 
 
    .classed("text-rect", true) 
 

 
// draw text 
 
const text = box 
 
    .append("text") 
 
    .attr("text-anchor", "start") 
 
    .attr("font-family", "Arial") 
 
    .attr("x", 0) // <- I set `x` to zero here 
 
    .attr("y", 0) 
 
    .text((d) => d.text) 
 
    .each(function(d){ d.textBBox = this.getBBox() }) 
 

 
// surround text using coorrdinates from `getBBox()` of `<text>` 
 
box 
 
    .append("rect") 
 
    .attr("x", (d) => d.textBBox.x - PADDING) 
 
    .attr("y", (d) => d.textBBox.y - PADDING) 
 
    .attr("width", (d) => d.textBBox.width + 2 * PADDING) 
 
    .attr("height", (d) => d.textBBox.height + 2 * PADDING) 
 
    .attr("fill", "none") 
 
    .attr("stroke", "black") 
 
    .attr("stroke-width", 1) 
 

 
// avoid overlap 
 
box 
 
    .each(function(d){ d.bbox = this.getBBox() }) 
 
    .attr("transform", function(d, i) { 
 
    let oldY = d.bbox.y 
 
    d.bbox.y = (i==0)? 0 : box.data()[i-1].bbox.y + box.data()[i-1].bbox.height 
 
    return `translate(${BOX_X},${d.bbox.y - oldY})` 
 
    }); 
 

 
// show coordinates 
 
const div = d3.select("div#coordinates") 
 
    .selectAll("p") 
 
    .data(text.data()) 
 
    .enter() 
 
    .append("p") 
 
    .text((d) => `"${d.text}": (${d.textBBox.x}, ${d.textBBox.y})`) 
 
// I set `x` attribute of `<text>` to zero, 
 
// but `getBBox()` returned a different x coordinate.
<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
 
    </head> 
 
    <body> 
 
    <h3>SVG is drawn here</h3> 
 
    <svg id="svg" width="150" height="150"></svg> 
 
    <hr> 
 
    <h3>XY coordinates are shown here</h3> 
 
    <div id="coordinates"></div> 
 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 
    </body> 
 
</html>

  1. Results of Chrome and Firefox
  2. Results of Different font-size
+1

有時候,通常是字距或襯線的原因,一個字母可能會重疊一點點其實際定位點的左側。邊界框反映了這一點。 –

+0

根據Paul LeBeau的鏈接,在並排放置的字母之間會出現字距變化。字距是否出現在一行的第一個字母中? – stolow

回答

2

這就是所謂的 「側軸承」。這是字符X位置和字形左側(或右側)之間的區別。例如,圓形字符(如「O」)可能需要略微向左側伸出,以便在與其他文字上下對齊時看起來光學正確。

以下圖片沒有說明這一點,但它確實顯示了方位是什麼。

enter image description here

來源:https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html

+0

根據字母的不同,左側軸承的數量也不同, 字母使用原點放置在''的'x'處;因此,字母的字形的左側不對齊。 當我調用'getBBox()'時,字形的邊界框被返回而沒有左側的方向,因此我獲得了不同的x座標。它是否正確? 但是,當指定更大的'font-size'時,'getBBox()。儘管左側軸承變大,x'變爲零。 – stolow

+0

否。當您在X處放置一個字符時,字符的(左側)方位可能意味着邊界框的minX與X不同。如果左側方位爲0,則X和minX應該相同。如果左側軸承小於零,字符將延伸到X的左側,因此bbox的minX將小於X.反之亦然,如果左側軸承大於零 - 如同案例中的示例字符。 –

相關問題