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

时间:2018-10-22 13:39:44

标签: svg text

我正在构建一个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>中的第一个元素,然后相对于外部坐标系放置最后一个项目(至少我还不知道该如何做)。

鉴于我对所有内容都使用百分比,是否可以按照我希望的方式旋转文本?

1 个答案:

答案 0 :(得分:0)

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

使用transform attributeCSS transforms进行的转换目前尚不完全兼容。 SVG rotate()函数无法可靠地跨浏览器获取单元标识符,而CSS rotate()函数没有用于旋转中心的参数,但可以使用transform-origin属性。因此,针对您的问题有两种解决方案。两者都以文本锚点作为旋转中心进行描述

CSS方式

transform-origin是一个CSS属性,它使用两个长度的列表来描述旋转中心。默认情况下,旋转中心是旋转对象的中心。对于文本内容,这可能对 vertical 中心的位置造成一些不确定性。最好定义一个明确的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 do not support使用这种语法。

SVG方式

SVG支持产生新坐标系的第二种机制:定义新视口。为此,您必须嵌套一个<svg>元素。当前不完全支持在transform元素上定义<svg>属性,但是您可以设置新的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的负值开始。