有没有办法在可调整大小的图形中可靠地旋转 SVG 文本?



我正在构建一个SVG,它显示带有轴标签的相当标准的X-Y图。我希望 y 轴标签(在图表的左侧(垂直显示,整个文本旋转 90 度。例如,要绘制velocity/time,y轴将是"速度",V显示在图形的顶部,"y"显示在底部。

我的 SVG 是用%计算的所有大小和距离构建的,因此例如一条线可以这样渲染:

<line x1="5%" y1="8%" x2="10%" y2="6%" />

这样做是为了"调整图形大小"以填充封闭应用程序、网页等提供给它的任何空间。

我知道如何旋转文本(transform="rotate(Θ, cx, cy)"(,但这不适用于cxcy值的百分比。我尝试将文本包装在<g>中并旋转它(同样使用<svg>(,但坐标系似乎是从父级继承的,所以我不能围绕<g><svg>的"原点"旋转,然后将最终项目相对于外部坐标系放置(至少我还没有弄清楚如何(。

鉴于我对所有内容都使用百分比,有没有办法以我想要的方式旋转文本?

首先要注意的是,变换不会继承元素,而是为元素及其所有子元素定义新的坐标系。这可能看起来像一个语义细节,但要理解 SVG,您需要从当前坐标系及其转换的角度来考虑,否则规范的大部分内容会显得令人困惑。

具有transform属性和 CSS 转换的转换目前并不真正兼容。SVGrotate()函数不能可靠地跨浏览器获取单位标识符,CSSrotate()函数没有旋转中心的参数,但可以使用transform-origin属性。因此,您的问题有两种解决方案。两者都以文本锚点作为旋转中心进行描述

CSS方式

transform-origin是一个 CSS 属性,它采用两个长度的列表来描述旋转中心。默认情况下,旋转的中心是旋转对象的中心。对于文本内容,这可能会对垂直中心的位置产生一些不确定性。最好定义显式transform-box:view-box并再次使用定位属性。

line {
stroke: red;
}
text {
font-family: sans-serif;
font-size: 15px;
}
.cross {
transform: rotate(90deg);
transform-origin: 20% 20%;
transform-box: view-box;
}
<svg width="200" height="150">
<line x1="20%" x2="20%" y1="0" y2="100%" />
<line x1="0" x2="100%" y1="20%" y2="20%" />
<text class="along" x="20%" y="20%">label</text>
<text class="cross" x="20%" y="20%">label</text>
</svg>

请注意,IE/Edge 不支持此语法。

SVG 方式

SVG 支持生成新坐标系的第二种机制:定义新视口。为此,您必须嵌套一个<svg>元素。虽然目前不完全支持在<svg>元素上定义transform属性,但您可以设置新的xy属性以有效地实现翻译。

这样,您可以先将文本定位在其局部坐标系的原点,将其旋转到位,然后才以百分比长度将其移动到新位置。

line {
stroke: red;
}
text {
font-family: sans-serif;
font-size: 15px;
}
svg svg {
overflow: visible;
}
<svg width="200" height="150">
<line x1="20%" x2="20%" y1="0" y2="100%" />
<line x1="0" x2="100%" y1="20%" y2="20%" />
<text class="along" x="20%" y="20%">label</text>
<svg x="20%" y="20%">
<!-- x, y and transform center all default to 0 -->
<text class="cross" transform="rotate(90)">label</text>
</svg>
</svg>

您需要在内部 svg 上设置overflow:visible,以确保最终位于新视口之外的内容仍然可见。(在上面的示例中,情况并非如此,但是如果您使用例如text-anchor:middle,则标签将从负 y 值开始。

最新更新