固定 SVG 中的笔画宽度

Posted

技术标签:

【中文标题】固定 SVG 中的笔画宽度【英文标题】:Fixed stroke width in SVG 【发布时间】:2010-11-21 01:30:01 【问题描述】:

我希望能够将 SVG 元素的笔画宽度设置为“像素感知”,无论当前应用的缩放转换如何,它始终为 1 像素宽。我知道这很可能是不可能的,因为 SVG 的重点是与像素无关。

上下文如下:

我有一个设置了 viewBox 和 preserveAspectRatio 属性的 SVG 元素。它看起来像这样

<svg version="1.1" baseProfile="full"
    viewBox="-100 -100 200 200" preserveAspectRatio="xMidYMid meet"
    xmlns="http://www.w3.org/2000/svg" >
</svg>

这意味着当我缩放那个元素时,它里面的实际形状会相应地缩放(到目前为止一切都很好)。

如您所见,我已经设置了 viewBox,使原点位于中心。我想在该元素内绘制一个 x 轴和一个 y 轴,我这样做:

<line x1="-1000" x2="1000" y1="0" y2="0" />

同样,这很好用。不过,理想情况下,这个轴总是只有 1px 宽。当我缩放父 svg 元素时,我对轴变得更胖不感兴趣。

那我是不是搞砸了?

【问题讨论】:

【参考方案1】:

这是基于 Erik 的回答的更简洁的回答,可帮助您快速入门。

<div style="background: blue; width: 100%; height: 130px;">
            <svg xml:id="root" viewBox="0 0 100 100"   preserveAspectRatio="none">
                <rect xml:id="r" vector-effect="non-scaling-stroke" x="0" y="0"   fill="none" stroke="#88CE02"
                      stroke-linecap="square" stroke- stroke-miterlimit="30"/>
            </svg>
        </div>

vector-effect="non-scaling-stroke" 添加到 SVG 矩形可以固定边框大小(或笔划大小)。

【讨论】:

【参考方案2】:

您可以使用设置为non-scaling-strokevector-effect 属性,请参阅the docs。另一种方法是使用transform(ref)

这将在支持 SVG Tiny 1.2 的那些部分的浏览器中工作,例如 Opera 10。后备包括编写一个小脚本来做同样的事情,基本上是反转 CTM 并将其应用于不应缩放的元素。

如果您想要更清晰的线条,您也可以disable antialiasing(shape-rendering=optimizeSpeedshape-rendering=crispEdges)和/或调整定位。

【讨论】:

不幸的是,这是在 XUL 应用程序中,似乎还不支持矢量效果。哦,好吧。 这应该会出现在 Firefox 15 中,一切正常,因此一旦在 gecko 15 上构建 XUL 应用程序,您应该能够使用它。 IE11 仍然不支持vector-effect 属性。能不能在IE11中达到和vector-effect: non-scaling-stroke一样的效果? @merlin 是的,用 js 可以在 IE 中模拟这个。 @merlin 克隆元素(将fill 设置为nonestroke 反之亦然),计算并设置适当的变换(一个用于填充部分,一个用于描边部分)。肯定会有点混乱,但它确实存在 - 您可能还想要求 Microsoft 添加对它的支持。无论如何,我认为您的问题应该是一个独立的问题。

以上是关于固定 SVG 中的笔画宽度的主要内容,如果未能解决你的问题,请参考以下文章

非固定宽度正后视

如何使 SVG 宽度响应但保持 SVG 高度不变?

Raphael JS 中的 Rect 在所有边上的笔画宽度不同

jQuery Panzoom 包含:在具有固定宽度的容器内“反转”

如何根据文本宽度动态调整 SVG 矩形的大小?

如何在不改变高度的情况下让 SVG 具有流畅的宽度?