完美水平路径的 SVG 渐变

Posted

技术标签:

【中文标题】完美水平路径的 SVG 渐变【英文标题】:SVG gradient for perfectly horizontal path 【发布时间】:2012-10-24 18:55:51 【问题描述】:

我正在使用 svg 绘制折线图,​​并且需要对其应用渐变。对于每一行,我使用一个路径元素并将笔画设置为我的线性渐变元素之一。

这适用于除纯水平线之外的所有内容 - 在这种情况下,我的线上根本没有颜色。

我做了一个小提琴来显示问题:http://jsfiddle.net/b6EQT/

<svg>
    <defs>
        <linearGradient id="grad" x1="0%" x2="100%" y1="0%" y2="0%">
            <stop class="" offset="0%" style="stop-color: red;"></stop>
            <stop class="" offset="33%" style="stop-color: yellow;"></stop>
            <stop class="" offset="66%" style="stop-color: pink;"></stop>
            <stop class="" offset="100%" style="stop-color: blue"></stop>
        </linearGradient>
    </defs>
<-- Gradient not applied -->
<path stroke="url(#grad)" d="M20,20L400,20" style="stroke-width: 10px;"></path>

<-- Gradient applied since height of 1px -->
<path stroke="url(#grad)" d="M20,40L400,41" style="stroke-width: 10px;"></path>

<-- Gradient applied because of fake initial "move to" -->
<path stroke="url(#grad)" d="M-1,-1,M20,60L400,60" style="stroke-width: 10px;"></path>
</svg>​

没有出现纯水平线(第一条路径),而第二条(y 略有变化)出现。

我尝试了一些小技巧来启动它 - 在开始时放置一个假的 M-1,-1,这似乎可以解决 IE 和 Chrome 中的问题,但不能解决 Firefox。这让我觉得我在理解 SVG 渐变和路径时遗漏了一些东西。有没有办法让它工作?

【问题讨论】:

【参考方案1】:

gradientUnits 的默认值为 objectBoundingBox。 specification text的最后一段描述了您遇到的关键问题...

当适用元素的几何形状没有宽度或没有高度时,不应使用关键字 objectBoundingBox,例如水平或垂直线的情况,即使该线在查看时由于具有非零值而具有实际粗细笔划宽度,因为边界框计算忽略笔划宽度。当适用元素的几何图形没有宽度或高度并且指定了 objectBoundingBox 时,将忽略给定的效果(例如,渐变或过滤器)。

如果你有一条水平线,为什么不使用带有填充的矩形而不是带有笔划的路径?或者使用 userSpaceOnUse 单位。

【讨论】:

图表是自动生成的,是否完美的水平取决于数据。不过,userSpaceOnUse 单元可以完美运行,谢谢! @XwipeoutX 如果您的路径是从您的数据动态生成的,那么一个选项可能是稍微抖动路径以使它们不是完全水平的。这样你就可以保留 objectBoundingBox,这可能更适合你,因为停靠点的百分比属于路径本身【参考方案2】:

gradientUnits="userSpaceOnUse" 可以修复它。

Demo

<linearGradient 
    id="grad" x1="0%" x2="100%" y1="0%" y2="0%" 
    gradientUnits="userSpaceOnUse">
    <stop class="" offset="0%" style="stop-color: red;"></stop>
    <stop class="" offset="33%" style="stop-color: yellow;"></stop>
    <stop class="" offset="66%" style="stop-color: pink;"></stop>
    <stop class="" offset="100%" style="stop-color: blue"></stop>
</linearGradient>

More detail answer

【讨论】:

以上是关于完美水平路径的 SVG 渐变的主要内容,如果未能解决你的问题,请参考以下文章

如何将动画渐变添加到 svg 路径?

svg路径元素中的定向渐变

我可以沿 SVG 路径应用渐变吗?

如何使用 SVG 滤镜创建透明渐变蒙版

如何给我的 SVG 图标冠上金色的线性渐变填充(路径)颜色? [复制]

SVG悬停时的平滑过渡线性渐变