SVG and jQuery: multiple lines of text will not ce

2019-08-17 02:59发布

This code is supposed to center the text vertically after changing some font properties.

The calculations look correct, but for some reason, the text isn't pushed down as far as the calculations say they should, causing the text to be off-center.

Codepen: https://codepen.io/anon/pen/NepNjb?editors=1111

What's causing this?

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<svg id="rootBox" width="375" height="812" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <style type="text/css">@import url('https://fonts.googleapis.com/css?family=Lato|Open+Sans|Oswald|Raleway|Roboto|Indie+Flower|Gamja+Flower')</style>

    <svg id="textBox1" class="textBox" x="0" y="0" width="100%" height="25%">
      <rect class="background" x="0%" y="0%" width="100%" height="100%" fill="gray" fill-opacity="0.5" />

      <text class="tspanGroup" x="50%" y="50%"><tspan x="50%" dy="0" text-anchor="middle">tspan line 0</tspan><tspan x="50%" dy="1.5em" text-anchor="middle">tspan line 1</tspan><tspan x="50%" dy="1.5em" text-anchor="middle">tspan line 2</tspan></text>
    </svg>

</svg>

1条回答
姐就是有狂的资本
2楼-- · 2019-08-17 03:48

Add dominant-baseline="hanging" to your .tspanGroup and alignment-baseline="middle" to your <tspan>s. This will fix the baseline-behaviour of the text elements.

To see the effect of the default values versus the altered values, change the y-value of your .tspanGroup to 0 in your pen and the snippet in this answer. You will see that the text flows over the upper edge in your example, while starting at the edge on mine.

console.log("Start");


function setTspan(elem, fontFamily, fontSize, fontStyle) {
  // Set font family?
  if (fontFamily) {
    elem.attr("font-family", fontFamily);
  }
  
  // Set font size?
  if (fontSize) {
    elem.attr("font-size", fontSize);
  }
  
  // Set font style?
  if (fontStyle) {
    elem.attr("font-style", fontStyle);
  }
}


function centerText() {  
  // Get tspan group.
  var textBox = $("#textBox1");
  var tspanGroup = textBox.children(".tspanGroup");

  // Set font styles.
  var fontSize = 30;
  var fontFamily = "Open-Sans";
  var fontStyle = "";
  tspanGroup.each(function(){
    setTspan($(this), fontFamily, fontSize, fontStyle);
  });
  
  // Get heights.
  var textBoxHeight = textBox[0].getBoundingClientRect().height;
  var tspanGroupClientRect = tspanGroup[0].getBoundingClientRect();

  // Update text
  var newY = textBoxHeight/2 - tspanGroupClientRect.height/2
  tspanGroup.attr("y", newY);
  
  // Print results
  console.log("Text box height: " + textBoxHeight + ". Tspan group height: " + tspanGroupClientRect.height + ". New Y: " + newY + ".");
}


centerText();


console.log("Done");
html, body {
  margin: 0;
  padding: 20px;
}
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<svg id="rootBox" width="375" height="812" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  
    <style type="text/css">@import url('https://fonts.googleapis.com/css?family=Lato|Open+Sans|Oswald|Raleway|Roboto|Indie+Flower|Gamja+Flower')</style>
        
    <svg id="textBox1" class="textBox" x="0" y="0" width="100%" height="25%">
      <rect class="background" x="0%" y="0%" width="100%" height="100%" fill="gray" fill-opacity="0.5" />
      
      <text class="tspanGroup" dominant-baseline="hanging" x="50%" y="50%"><tspan x="50%" dy="0" text-anchor="middle" alignment-baseline="hanging">tspan line 0</tspan><tspan x="50%" dy="1.5em" text-anchor="middle" alignment-baseline="hanging">tspan line 1</tspan><tspan x="50%" dy="1.5em" text-anchor="middle" alignment-baseline="hanging">tspan line 2</tspan></text>
    </svg>
    
</svg>

查看更多
登录 后发表回答