内联svg:使图像宽度适合其内容

时间:2016-12-20 17:44:41

标签: html svg

请考虑以下代码。我能够使两个内联svg符合各自的文本内容吗?即“Teststring.Lorem。”应该更长,“foo”更短。我需要两个相同的svg,内容文本是唯一的区别。目前它们的静态宽度为50px。

我知道我可以通过HTML + CSS轻松实现这一点,但在我的真实世界场景中,我需要在文本后面使用SMIL动画,这是最简单的方法。我已经有了(更复杂的)替代品,所以这不是我想要的。我只是想知道这是否可行,如果可能的话。所以“它根本无法工作,尝试不同的东西”将是一个有效的答案。 (虽然不是我希望的东西。)

<svg width="50" height="20" viewBox="0 0 50 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<foreignObject x="0" y="0" width="50" height="20">
		<body xmlns="http://www.w3.org/1999/xhtml">
			Teststring. Lorem.
		</body>
	</foreignObject>
	<rect x="0" y="0" width="50" height="20" fill="rgba(0,0,0,.3)"></rect>
</svg><br>

<svg width="50" height="20" viewBox="0 0 50 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<foreignObject x="0" y="0" width="50" height="20">
		<body xmlns="http://www.w3.org/1999/xhtml">
			foo
		</body>
	</foreignObject>
	<rect x="0" y="0" width="50" height="20" fill="rgba(0,0,0,.3)"></rect>
</svg>

1 个答案:

答案 0 :(得分:0)

我不确定以下是否是正确的方法,但它确实有效。

解决方案的说明

svg中的文本包含在span标记中。在onload事件中,svg标记的宽度设置为通过javascript测量的span元素的宽度。不幸的是,你必须为svg标签设置一个单独的id,并相应地调整javascript代码第一行中的id字符串。

设置新宽度

您还需要将新宽度设置为svg中的所有相关元素。如果你有很多元素,这可能会变得有点难看。 可能的快捷方式可以是操纵变换属性的组元素。这会将组的内容缩放到正确的大小,同时保留属性。如下所示:

//javascript
thisSvg.getElementsByClassName('group')[0].setAttribute(
    'transform', 'scale('+textWidth/50+')');

<!--svg-->
<g class="group">
    <rect x="0" y="0" width="50" height="20" fill="rgba(0,0,0,.3)"></rect>
    <rect x="0" y="0" width="25" height="20" fill="rgba(1,0,0,.3)"></rect>
</g>

实际解决方案

<svg id="custom-id-1" width="50" height="20" viewBox="0 0 50 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="
  var thisSvg = document.getElementById('custom-id-1');
  var box = thisSvg.getElementsByClassName('text')[0].getBoundingClientRect();
  var textWidth = box.right-box.left;
  thisSvg.setAttribute('viewBox', '0 0 '+textWidth+' 20');
  thisSvg.setAttribute('width', textWidth);
  thisSvg.getElementsByClassName('foreign')[0].setAttribute('width', textWidth);
  thisSvg.getElementsByClassName('rect')[0].setAttribute('width', textWidth);
">
	<foreignObject class="foreign" x="0" y="0" width="50" height="20">
		<body xmlns="http://www.w3.org/1999/xhtml">
			<span class="text" style="white-space:nowrap">Teststring. Lorem.</span>
		</body>
	</foreignObject>
	<rect class="rect" x="0" y="0" width="50" height="20" fill="rgba(0,0,0,.3)"></rect>
</svg><br>

<svg id="custom-id-2" width="50" height="20" viewBox="0 0 50 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="
  var thisSvg = document.getElementById('custom-id-2');
  var box = thisSvg.getElementsByClassName('text')[0].getBoundingClientRect();
  var textWidth = box.right-box.left;
  thisSvg.setAttribute('viewBox', '0 0 '+textWidth+' 20');
  thisSvg.setAttribute('width', textWidth);
  thisSvg.getElementsByClassName('foreign')[0].setAttribute('width', textWidth);
  thisSvg.getElementsByClassName('rect')[0].setAttribute('width', textWidth);
">
	<foreignObject class="foreign" x="0" y="0" width="50" height="20">
		<body xmlns="http://www.w3.org/1999/xhtml">
			<span class="text" style="white-space:nowrap">foo</span>
		</body>
	</foreignObject>
	<rect class="rect" x="0" y="0" width="50" height="20" fill="rgba(0,0,0,.3)"></rect>
</svg>