SVG:如何根据 <Rect/> 位置和大小以编程方式将 <Text/> 居中

SVG: How to programmatically center an <Text/> based on <Rect/> position and size

提问人:Evry 提问时间:12/20/2021 更新时间:12/20/2021 访问量:138

问:

我在 Figma 上制作了这个数独板

enter image description here

我想使用 ReactJS 把它放在我的网站上。我的目标是将事件侦听器添加到矩形中,并根据用户按 1-9 数字更改值(就像数独一样)。问题是我不知道如何根据 (x,y) 位置和大小以编程方式定位。textrect

例如:

<g x="7.49219" y="4.37108" width="34.8721" height="34.8721">
       <rect
            x="7.49219"
            y="4.37108"
            width="34.8721"
            height="34.8721"
            rx="4.75"
            stroke="#D5D5D5"
            stroke-width="0.5"
       />
       <text id="text_test" fill="red" fontSize={24}>
           5
       </text>
</g>

我计算出文本位置为

x = rectXPos + (rectWidth / 2)

y = rectYPos + (rectHeight / 2)

但它给了我:

enter image description here

我想考虑公式中的文本宽度和高度以居中。但我只是在浏览器上获取以像素为单位的文本大小

enter image description here

因此,当我尝试将公式更新为

x = rectXPos + (rectWidth / 2) - (textWidth / 2)

y = rectYPos + (rectHeight / 2) + (textHeight / 2)

我明白了:

enter image description here

X 位置有效,但 Y 无效。

  1. 我错过了什么?
  2. 有没有更好的方法来实现我想要的东西?
CSS 反应JS SVG

评论

1赞 Hunter McMillen 12/20/2021
您必须使用 SVG 吗?使用 HTML 和 CSS 布置网格会容易得多。
0赞 enxaneta 12/20/2021
将 和 作为属性或 css 用于文本text-anchor="middle"text-anchor="middle"
0赞 Evry 12/20/2021
@HunterMcMillen 好吧,我有点想学习如何使用 SVG,但如果在这种情况下它似乎是一个糟糕的选择,那么我将仅更改为 HTML
0赞 Evry 12/20/2021
@enxaneta它不起作用,它会将文本与 SVG 中心对齐,我必须根据 rect 对齐
0赞 enxaneta 12/20/2021
您正在将矩形的计算中心用作文本的 X 和 Y 属性

答:

1赞 chrwahl 12/20/2021 #1

您可以使用属性重新排列文本元素,并将位置设置为预期“框架”的中间位置。因此,在这种情况下,和具有相同的起点。是 40x40,然后需要在 20,20 中。text-anchor="middle"dominant-baseline="middle"<rect><text><rect><text>

从示例中可以看出,您可以使用其属性转换/翻译来移动元素。这为糊状代码提供了更具可读性的代码,因为您需要放置 9x9 的元素。<g>

如果要在浏览器中使用,我建议您使用 CSS 进行样式设置。比如用样式表替换属性等,如下所示:stroke

svg.sudoku rect {
  stoke: #D5D5D5;
  stroke-width: .5px;
}

<svg viewBox="0 0 200 200">
  <g transform="translate(5 5)">
    <g transform="translate(0 0)">
      <rect
        width="40"
        height="40"
        rx="4.75"
        stroke="#D5D5D5"
        stroke-width="0.5"
        fill="none"
        />
      <text x="20" y="20" text-anchor="middle" dominant-baseline="middle" fill="red" font-size="20">5</text>
    </g>
    <g transform="translate(45 0)">
      <rect
        width="40"
        height="40"
        rx="4.75"
        stroke="#D5D5D5"
        stroke-width="0.5"
        fill="none"
        />
      <text x="20" y="20" text-anchor="middle" dominant-baseline="middle" fill="red" font-size="20">2</text>
    </g>
  </g>
</svg>