如何在SVG矩形中放置和居中文本
我有以下矩形…
<rect x="0px" y="0px" width="60px" height="20px"/>
我想把“小说”一词置于其中。 对于其他矩形,是否保留在其中的svg文字? 我似乎无法find任何具体的内容插入在水平和垂直居中的形状和文字换行的文字。 此外,文字不能离开矩形。
查看http://www.w3.org/TR/SVG/text.html#TextElement示例没有帮助,因为文本元素的x和y不同于矩形的x和y。 文字元素似乎没有宽度和高度。 我不确定这里的math。
(我的HTML表只是不会工作。)
SVG 1.2 Tiny添加了文本包装,但是在浏览器中find的大多数SVG实现(除了Opera)都没有实现这个function。 开发人员通常需要手动定位文本。
SVG 1.1规范提供了这个限制的一个很好的概述,以及克服它的可能的解决scheme:
每个“文本”元素都会导致呈现单个文本string。 SVG不执行自动换行或换行。 要实现多行文本的效果,请使用以下方法之一:
- 作者或创作包需要预先计算换行符,并使用多个“文本”元素(每行文本一个)。
- 作者或创作包需要预先计算换行符,并为属性“x”,“y”,“dx”和“dy”使用带有一个或多个“tspan”子元素的单个“文本”元素。为那些开始换行的字符设置新的起始位置。 (这种方法允许跨多行文本select用户文本 – 请参阅文本select和剪贴板操作。)
- 将文本显示在另一个XML名称空间中,例如embedded在“foreignObject”元素中的XHTML [XHTML]。 (注意:这个方法的确切语义目前还没有完全定义。)
http://www.w3.org/TR/SVG11/text.html#Introduction
作为一个基元,文本包装可以通过使用dy属性和tspan元素来模拟,正如在规范中提到的那样,一些工具可以自动执行此操作。 例如,在Inkscape中,select所需的形状和所需的文本,然后使用文本 – >stream入帧。 这将允许你写你的文字,包装,这将基于形状的界限包装。 此外,请确保按照以下说明通知Inkscape保持与SVG 1.1的兼容性: http : //wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F
此外,还有一些JavaScript库可用于dynamic自动化文本换行: http : //www.carto.net/papers/svg/textFlow/
有趣的是,CSVG的解决scheme是将一个形状包装成一个文本元素(例如参见他们的“button”示例),不过有一点很重要,那就是他们的实现在浏览器中是不可用的: http : //www.csse.monash.edu .AU /〜CLM / csvg / about.html
我提到这一点是因为我开发了一个CSVG启发式的库,允许你做类似的事情,并且可以在networking浏览器中工作,尽pipe我还没有发布它。
在SVG中水平和垂直居中文本的简单解决scheme:
-
将文本的位置设置为要将其居中的元素的绝对中心 :
- 如果是父母,你可以做
x="50%" y ="50%"
。 - 如果是另一个元素,则
x
将是该元素的x
+宽度的一半(对于y
相似的,但是具有高度)。
- 如果是父母,你可以做
-
使用
text-anchor
属性将文本水平放置在值middle
:中间
渲染的字符alignment,使得生成的渲染文本的几何中间位于当前的文本初始位置。
-
使用
alignment-baseline
属性将文本垂直middle
放置(或根据您希望的样子,您可能需要central
)
这是一个简单的演示:
<svg width="200" height="100"> <rect x="0" y="0" width="200" height="100" stroke="red" stroke-width="3px" fill="white"/> <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">TEXT</text> </svg>
你可以直接使用text-anchor = "middle"
属性。 我build议在你的矩形和文本上创build一个包装svg元素。 这样你可以使用一个CSSselect器来使用整个元素。 确保将文本的“x”和“y”属性设置为50%。
<svg class="svg-rect" width="50" height="40"> <rect x="0" y="0" rx="3" ry="3" width="50" height="40" fill="#e7e7e7"></rect> <text x="50%" y="50%" text-anchor="middle" stroke="black" stroke-width="1px" dy=".3em">N/A</text> </svg>
以前的答案使用圆angular或大于1的stroke-width
时效果不佳。 例如,你会期望下面的代码产生一个圆angular的矩形,但是边angular被父svg
组件剪裁:
<svg width="200" height="100"> <!--this rect should have rounded corners--> <rect x="0" y="0" rx="5" ry="5" width="200" height="100" stroke="red" stroke-width="10px" fill="white"/> <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CLIPPED BORDER</text> </svg>
我有一个使用SVG获取任何东西的bug,所以我推出了我自己的小function。 希望它应该帮助你。 请注意,它只适用于SVG元素。
function centerinparent(element) { //only works for SVG elements var bbox = element.getBBox(); var parentwidth = element.parentNode.width.baseVal.value; var parentheight = element.parentNode.height.baseVal.value; var newwidth = ((parentwidth / 2) - (bbox.width / 2)) - 2; //i start everything off by 2 to account for line thickness var newheight = ((parentheight / 2) - (bbox.height / 2)) - 2; //need to adjust for line thickness?? if (element.classList.contains("textclass")) { //text is origined from bottom left, whereas everything else origin is top left newheight += bbox.height; //move it down by its height } element.setAttributeNS(null, "transform", "translate(" + newwidth + "," + newheight + ")"); // console.log("centering BOXES: between width:"+element.parentNode.width.baseVal.value + " height:"+parentheight); // console.log(bbox); }
在矩形内插入文本的一种方法是在rect对象内部插入一个外部对象,这是一个DIV。
这样,文本将会抑制DIV的限制。
var g = d3.select("svg"); g.append("rect") .attr("x", 0) .attr("y", 0) .attr("width","100%") .attr("height","100%") .attr("fill","#000"); var fo = g.append("foreignObject") .attr("width","100%"); fo.append("xhtml:div") .attr("style","width:80%;color:#FFF;margin-right: auto;margin-left: auto;margin-top:40px") .text("Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis");
<script src="ajax/libs/d3/4.9.1/d3.js"></script> <svg width="200" height="200"></svg>
全部细节博客: http : //blog.techhysahil.com/svg/how-to-center-text-in-svg-shapes/
<svg width="600" height="600"> <!-- Circle --> <g transform="translate(50,40)"> <circle cx="0" cy="0" r="35" stroke="#aaa" stroke-width="2" fill="#fff"></circle> <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text> </g> <!-- In Rectangle text position needs to be given half of width and height of rectangle respectively --> <!-- Rectangle --> <g transform="translate(150,20)"> <rect width="150" height="40" stroke="#aaa" stroke-width="2" fill="#fff"></rect> <text x="75" y="20" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text> </g> <!-- Rectangle --> <g transform="translate(120,140)"> <ellipse cx="0" cy="0" rx="100" ry="50" stroke="#aaa" stroke-width="2" fill="#fff"></ellipse> <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text> </g> </svg>