svg路径元素中的定向渐变

Posted

技术标签:

【中文标题】svg路径元素中的定向渐变【英文标题】:directed gradient in svg's path element 【发布时间】:2018-02-05 14:34:51 【问题描述】:

我正在编写一个显示图表并显示依赖关系的简单网页。我发现path 元素在svg 中的呈现方式出现了意外行为。

这是示例的完整 html

<html>
    <body>
        <svg id="svgConnections" xmlns="http://www.w3.org/2000/svg" style="width: 300px; height: 120px">
            <defs>
                <linearGradient id="grad1" >
                <stop offset="0%" style="stop-color:yellow;stop-opacity:1" />
                <stop offset="100%" style="stop-color:red;stop-opacity:1" />
                </linearGradient>
            </defs>            
            <path d="M40,40 L100,100 Z" stroke="url(#grad1)" strokeWidth="1px" />
            <path d="M200,100 L140,40 Z" stroke="url(#grad1)" strokeWidth="1px" />
        </svg>
    </body>
</html>

同样的例子在https://jsfiddle.net/4fLjm0e2/

让我烦恼的是,从左上角到右下角的第一行看起来与第二行“相反”:从右下角到左上角。

如何让路径始终以黄色开始并以红色结束?

【问题讨论】:

我刚刚阅读了文档,但没有找到任何可以轻松帮助您的内容。一种解决方案是根据线的方向设置x1x2y1y1&lt;linearGraient&gt; 的属性),但我希望有一个简单的解决方案。 【参考方案1】:

这不是错误。这是理解上的问题。

线性渐变的默认行为是沿水平线从对象的左侧过渡到其右侧。无论您是从左到右还是从右到左绘制路径都没有关系。在这两种情况下,渐变都会按照默认设置从左到右显示。

考虑下面的演示:

<svg   xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="grad1" gradientUnits="userSpaceOnUse">
      <stop offset="0%" style="stop-color:yellow;stop-opacity:1" />
      <stop offset="100%" style="stop-color:red;stop-opacity:1" />
    </linearGradient>
  </defs>
  <g stroke->
    <path d="M10,40 L110,40 Z" stroke="url(#grad1)" />
    <path d="M110,70 L10,70 Z" stroke="url(#grad1)" />
  </g>
</svg>

如果您希望颜色的过渡发生在垂直线或以一定角度的线,则必须使用 x1y1 属性及其以x2y2 属性结束的点。

我们不会将停靠点复制到每个&lt;linearGradient&gt; 元素中,而是使用xlink:href 属性来引用原始渐变。停靠点将被继承,但 x 和 y 坐标将被每个单独的渐变覆盖。

<linearGradient id="grad1" x1="0" y1="0" x2="1" y2="1">
  <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
  <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
<linearGradient id="grad2" xlink:href="#grad1" x1="1" y1="1" x2="0" y2="0"></linearGradient>

扩展上面的例子:

<svg   xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="grad1" gradientUnits="userSpaceOnUse">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
    <linearGradient id="grad2" xlink:href="#grad1" x1="120" y1="0" x2="0" y2="0"></linearGradient>
  </defs>
  <g stroke->
    <path d="M10,40 L110,40" stroke="url(#grad1)" />
    <path d="M110,70 L10,70 Z" stroke="url(#grad2)" />
  </g>
</svg>

在您的示例中,您使用的是对角路径,因此我们需要覆盖 &lt;linearGradient&gt; 元素的 x1y1x2y2 属性。

第一个 &lt;linearGradient&gt; 元素上的这些值将覆盖默认的从左到右设置,以生成从左上角到右下角的对角线渐变。 在&lt;linearGradient&gt; 元素上,这些值将改变渐变的方向,即从底部到顶部。

现在我们可以将这些渐变应用到各自的路径上。

<svg   xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="grad1" x1="0" y1="0" x2="1" y2="1">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
    <linearGradient id="grad2" xlink:href="#grad1" x1="1" y1="1" x2="0" y2="0"></linearGradient>
  </defs>
  <g stroke->
    <path d="M40,40 L100,100 Z" stroke="url(#grad1)" />
    <path d="M200,100 L140,40 Z" stroke="url(#grad2)" />
  </g>
</svg>

注意:这个Question 在当前问题的上下文中很有用。

【讨论】:

以上是关于svg路径元素中的定向渐变的主要内容,如果未能解决你的问题,请参考以下文章

D3 SVG 路径未填充线性比例渐变

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

除了数据 url 之外,如何让伪元素上的剪辑路径 SVG 在 IE11/Edge 中工作?

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

如何给SVG填充和描边应用径向渐变

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