如何在SVG矩形中放置和居中文本

Lad*_*ena 132 svg text

我有以下矩形......

<rect x="0px" y="0px" width="60px" height="20px"/>
Run Code Online (Sandbox Code Playgroud)

我想把"小说"这个词放在其中.对于其他矩形,svg自动换行保留在其中吗?我似乎无法找到任何具体的关于在水平和垂直居中以及自动换行的形状中插入文本的内容.此外,文本不能离开矩形.

查看http://www.w3.org/TR/SVG/text.html#TextElement示例没有帮助,因为文本元素的x和y与矩形的x和y不同.文本元素似乎没有宽度和高度.我不确定这里的数学.

(我的html表无法正常工作.)

Alv*_*oro 224

在SVG中水平和垂直居中文本的简单解决方案:

  1. 将文本的位置设置为要将其居中的元素的绝对中心:

    • 如果它是父母,你可以这样做x="50%" y ="50%".
    • 如果它是另一个元素,xx是该元素的一半+宽度的一半(并且与y高度类似).
  2. 使用text-anchor属性将文本水平居中,其值为middle:

    中间

    对齐渲染的字符,使得得到的渲染文本的几何中间位于初始当前文本位置.

  3. 使用该dominant-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%" dominant-baseline="middle" text-anchor="middle">TEXT</text>    
</svg>
Run Code Online (Sandbox Code Playgroud)

  • `dominant-baseline="central"` 给出了我想要的外观,FWIW (8认同)
  • 在我的例子中,它是`dominant-baseline`属性来完成工作,而不是`alignment-baseline`. (7认同)
  • 我一直在到处寻找这么简单的解决方案 - 没有其他东西对我有用我用它来将数字居中放在径向进度条内 (4认同)
  • 如果您打算定期执行此操作,还可以添加以下内容:`&lt;style type="text/css"&gt;&lt;![CDATA[ text { alignment-baseline: middle; 文本锚:中间;} ]]&gt;&lt;/style&gt;`。感谢您的解决方案。 (2认同)
  • @RegisMay 感谢您指出。我在 Mac 上的 Chrome 上,它与 `alignment-baseline` 一起工作得很好,但似乎这可能是一件古怪的事情,因为查看规范,它应该是 `text` 的 `dominant-baseline` 和 `alignment-baseline` ` 用于 `tspan`、`tref`、`altGlyph` 和 `textPath`。我相应地更新了答案。 (2认同)

jbe*_*rd4 37

SVG 1.2 Tiny添加了文本包装,但您在浏览器中找到的大多数SVG实现(Opera除外)都没有实现此功能.通常由您(开发人员)手动定位文本.

SVG 1.1规范提供了对此限制的良好概述,以及克服它的可能解决方案:

每个'text'元素都会导致呈现单个文本字符串.SVG不执行自动换行或自动换行.若要实现多行文本的效果,请使用以下方法之一:

  • 作者或创作包需要预先计算换行符并使用多个"文本"元素(每行文本一个).
  • 作者或编辑程序包需要预先计算换行和使用一个单一的"文本"元件与一个或多个"TSPAN"子元素与属性的"x"的适当值,"Y","DX"和"DY"为那些开始新行的字符设置新的起始位置.(此方法允许跨多行文本选择用户文本 - 请参阅文本选择和剪贴板操作.)
  • 表示要在另一个XML命名空间中呈现的文本,例如嵌入在"foreignObject"元素内的XHTML [XHTML].(注意:此方法的确切语义目前尚未完全定义.)

http://www.w3.org/TR/SVG11/text.html#Introduction

作为原语,可以使用dy属性和tspan元素模拟文本换行,并且如规范中所述,某些工具可以自动执行此操作.例如,在Inkscape中,选择所需的形状和所需的文本,然后使用"文本" - >"流入框架".这将允许您使用包装来编写文本,这将根据形状的边界进行换行.此外,请确保按照这些说明告诉Inkscape保持与SVG 1.1的兼容性:http: //wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F

此外,还有一些JavaScript库可用于动态自动化文本换行:http: //www.carto.net/papers/svg/textFlow/

有趣的是注意CSVG的解决方案,包装的形状到一个文本元素(例如,见他们的"按钮"的例子),尽管它一提的是其实施是非常重要的不是使用在浏览器中: http://www.csse.monash.edu .AU /〜CLM/csvg/about.html

我之所以提到这一点,是因为我开发了一个受CSVG启发的库,允许你做类似的事情并且可以在网络浏览器中工作,尽管我还没有发布它.

  • 甚至不让我开始创建*editable*text所涉及的内容...... (8认同)
  • @Erik,Opera再次领先于曲线. (2认同)

Aus*_*n D 19

使用圆角或者stroke-width> 1 时,之前的答案结果不佳.例如,您希望以下代码生成一个圆角矩形,但是父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>
Run Code Online (Sandbox Code Playgroud)

相反,我建议将texta 包装在一个svg然后将新的svgrect一起嵌套在g元素中,如下例所示:

<!--the outer svg here-->
<svg width="400px" height="300px">

  <!--the rect/text group-->
  <g transform="translate(50,50)">
    <rect rx="5" ry="5" width="200" height="100" stroke="green" fill="none" stroke-width="10"/>
    <svg width="200px" height="100px">
      <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CORRECT BORDER</text>      
    </svg>
  </g>

  <!--rest of the image's code-->
</svg>
Run Code Online (Sandbox Code Playgroud)

这解决了上面答案中出现的剪裁问题.我还使用该transform="translate(x,y)"属性翻译了rect/text组,以证明这提供了一种更直观的方法来在屏幕上定位rect/text.


Dan*_*man 13

派对晚了 11 年...使用 pathLength

x="50%" y ="50%"不适用于复杂的 SVG

没有人提及pathLength

  • 让它pathLength="2"在这里path id="#P"
  • 然后使用path以下中的作为指南textPath href="#P"
  • startoffset="1"蓝色路径的中间也是如此
  • text-anchor="middle"对齐文本
  • (用描边=“透明”隐藏蓝线)
  • (或者不使用pathLength并设置startoffset =“50%”)

<svg viewbox="0 0 200 50" style="background:pink">
  <rect x="10" y="10" width="180" height="30" stroke="green" fill="none"/>
  <path id="P" pathLength="2" d="M10 25h180" stroke="blue"/>
  <text>
    <textPath href="#P" 
              startoffset="1" text-anchor="middle" dominant-baseline="middle"
              fill="black" font-size="14px">aligned in middle</textPath>
  </text>
</svg>
Run Code Online (Sandbox Code Playgroud)


zoo*_*tos 10

您可以直接使用text-anchor = "middle"财产.我建议在矩形和文本上创建一个包装器svg元素.这样你就可以使用一个css选择器来使用整个元素.确保将文本的"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>
Run Code Online (Sandbox Code Playgroud)


Reg*_*May 7

alignment-baseline不是在这里使用的正确属性。正确的答案是使用组合dominant-baseline="central"text-anchor="middle"

<svg width="200" height="100">
    <g>
        <rect x="0" y="0" width="200" height="100" style="stroke:red; stroke-width:3px; fill:white;"/>
        <text x="50%" y="50%" style="dominant-baseline:central; text-anchor:middle; font-size:40px;">TEXT</text>
    </g>
</svg>
Run Code Online (Sandbox Code Playgroud)


Bre*_*ung 7

如果您以编程方式创建SVG,则可以对其进行简化并执行以下操作:

  <g>
      <rect x={x} y={y} width={width} height={height} />
      <text
          x={x + width / 2}
          y={y + height / 2}
          dominantBaseline="middle"
          textAnchor="middle"
      >
          {label}
      </text>
  </g>
Run Code Online (Sandbox Code Playgroud)

  • 不应该是`dominant-baseline`和`text-anchor`,而不是`dominantBaseline`和`textAnchor`吗? (4认同)
  • @NathanielM.Beaver 是的,应该是。接得好。上面的代码来自 React,不幸的是它需要使用驼峰命名法重命名属性。 (2认同)

Sah*_*pta 5

详细博客: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>
Run Code Online (Sandbox Code Playgroud)