【问题标题】:SVG: changing dy attribute does not change bounding rectangle height for parent text elementSVG:更改 dy 属性不会更改父文本元素的边界矩形高度
【发布时间】:2019-05-21 14:11:04
【问题描述】:

目标是垂直和水平对齐一组tspan元素。

但是,父容器不考虑 dy 值。

这会导致对齐问题。

如果您使用此 Codepen 的 dy 值,文本容器的高度始终保持不变:https://codepen.io/anon/pen/WLpvrG?editors=1111

如何获得 tspan 元素的准确边界矩形?

<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="0" y="0"><tspan x="50%" dy="0em" 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>

【问题讨论】:

  • 文本容器的高度很好。当您更改 first tspan 元素的 dy 时,它并不擅长,因为您实际上只是将其向下移动而不是更改其高度。请记住,dy 属性表示沿 y 轴移动。它并不表示调整大小。一个简单的解决方法是添加一个不可见的 tspan 元素作为第一个元素(不要给它任何内容)并使用第二个元素。
  • @icecub 你可以发帖作为答案来获得信用吗?谢谢。
  • @icecub 你还推荐一种更好的方法来垂直/水平居中文本元素吗?感谢您的帮助!

标签: javascript html svg


【解决方案1】:

dy 属性表示沿 y 轴的偏移。它并不表示调整大小。因此,如果您在 first &lt;tspan&gt; 元素上更改该值,您只是将其向上或向下移动。由于容器包裹着元素,因此只要移动它们,它就不会改变大小。

如果你想将文本垂直和水平居中,我建议你看看这里的第二个答案:How to place and center text in an SVG rectangle。我真的没有看到复制/粘贴它的意义,哈哈。

好的,我花了一点时间让它开始工作,但现在你开始了:

// Wait for document to load so the elements don't return undefined
document.addEventListener("DOMContentLoaded", function(event) {
	// Center the text
	centerText();

	setTimeout(function() {
		// Change font sizes
		document.getElementById('size1').style.fontSize = "12px";
		document.getElementById('size2').style.fontSize = "16px";
		document.getElementById('size3').style.fontSize = "20px";

		// Center the text again
		centerText();
	}, 3000);
});

function centerText(){
	// Get the elements
	const container = document.getElementById('textBox1');
	const textEle = document.getElementById('txt');

	// User getBBox for SVG element data
	const cBox = container.getBBox();
	const tBox = textEle.getBBox();

	// Get width / height of container SVG
	const contHeight = cBox.height;
	const contWidth = cBox.width;

	// Get width / height of TEXT element
	const txtHeight = tBox.height;
	const txtWidth = tBox.width;

	// Set the attributions correctly to center text
	textEle.setAttribute("x", (contWidth/2)-(txtWidth/2));
	textEle.setAttribute("y", (contHeight/2)-(txtHeight/2));
}
<svg id="rootBox" width="375" height="812" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<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%" dominant-baseline="middle" text-anchor="middle" id="txt">
			<tspan x="50%" dy="0em" id="size1">tspan line 0</tspan>
			<tspan x="50%" dy="1.5em" id="size2">tspan line 1</tspan>
			<tspan x="50%" dy="1.5em" id="size3">tspan line 2</tspan>
		</text>
	</svg>
</svg>

【讨论】:

  • 谢谢!但是为什么更改第二个和第三个 dy 值会影响文本高度?
  • @Crashalot 因为如果你这样做,第一个会留在原地。这就像你有3行。如果将第一个向下移动,它仍然是 3 行。但如果你移动第二或第三行,它就会变成 4、5 等行。只是中间一片空白。这使它更大。
  • @Crashalot 作为提示,我建议您使用浏览器的“检查元素”功能。只需右键单击它并检查它。然后,当您将代码悬停在检查器中时,它会通过在屏幕上绘制线条来显示元素的大小。这样就很容易准确地看到正在发生的事情。如果你问我,这绝对是前端设计工作的必备品。
  • 谢谢!还有任何线索为什么这些线不会居中? codepen.io/anon/pen/royxNx?editors=1010
  • @Crashalot 是的,因为您使用的是 tspan 元素。因此,中心点成为第一行的开始。我认为您必须使用JS来计算&lt;text&gt;元素的宽度和高度,然后将x属性设置为calc(50% - half width of text),将y设置为calc(50% - half height of text)
猜你喜欢
  • 2015-12-24
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2013-06-28
  • 2013-05-20
相关资源
最近更新 更多