SVG:如何根据 <Rect/> 位置和大小以编程方式使 <Text/> 居中
SVG: How to programmatically center an <Text/> based on <Rect/> position and size
我在 Figma 上制作了这个数独板
并且我想使用 ReactJS 将它放在我的网站上。我的目标是将事件侦听器添加到矩形并根据用户按下 1-9 数字更改值(就像数独游戏一样)。问题是我不知道如何根据 rect
(x,y) 位置和大小以编程方式定位 text
。
例如:
<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)
但它给了我:
我想考虑公式中的文本宽度和高度使其居中。但我只是在浏览器上获得以像素为单位的文本大小
所以当我尝试将公式更新为
x = rectXPos + (rectWidth / 2) - (textWidth / 2)
y = rectYPos + (rectHeight / 2) + (textHeight / 2)
我明白了:
X 位置有效但 Y 无效。
- 我错过了什么?
- 有没有更好的方法来实现我想要的?
您可以重新排列具有属性 text-anchor="middle"
和 dominant-baseline="middle"
的文本元素,并将位置设置在预期“框架”的中间。因此,在这种情况下,<rect>
和 <text>
具有相同的起点。 <rect>
是 40x40 然后 <text>
需要在 20,20.
从示例中可以看出,您可以使用 <g>
及其属性 transform/translate 来移动元素。既然您有 9x9 的元素需要放置,这将提供更易读的代码。
如果要在浏览器中使用它,我建议您使用 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>
我在 Figma 上制作了这个数独板
并且我想使用 ReactJS 将它放在我的网站上。我的目标是将事件侦听器添加到矩形并根据用户按下 1-9 数字更改值(就像数独游戏一样)。问题是我不知道如何根据 rect
(x,y) 位置和大小以编程方式定位 text
。
例如:
<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)
但它给了我:
我想考虑公式中的文本宽度和高度使其居中。但我只是在浏览器上获得以像素为单位的文本大小
所以当我尝试将公式更新为
x = rectXPos + (rectWidth / 2) - (textWidth / 2)
y = rectYPos + (rectHeight / 2) + (textHeight / 2)
我明白了:
X 位置有效但 Y 无效。
- 我错过了什么?
- 有没有更好的方法来实现我想要的?
您可以重新排列具有属性 text-anchor="middle"
和 dominant-baseline="middle"
的文本元素,并将位置设置在预期“框架”的中间。因此,在这种情况下,<rect>
和 <text>
具有相同的起点。 <rect>
是 40x40 然后 <text>
需要在 20,20.
从示例中可以看出,您可以使用 <g>
及其属性 transform/translate 来移动元素。既然您有 9x9 的元素需要放置,这将提供更易读的代码。
如果要在浏览器中使用它,我建议您使用 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>