【问题标题】:Gradient across path in SVGSVG中跨路径的渐变
【发布时间】:2017-09-12 20:09:43
【问题描述】:

我在 SVG 中有一个非常简单的路径。

<svg
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 57" 
    version="1.1" x="0px" y="0px">
    <defs>
        <style type="text/css"><![CDATA[
            ]]>
        </style>
    </defs>
    <path id="pipe" d="
        M8.0178,52.0035
        L27.0178,52.0035
        C42.4568,52.0035 55.0178,39.4425 55.0178,24.0035
        L55.0178,8.0035
        L43.0178,8.0035
        L43.0178,24.0035
        C43.0178,32.8255 35.8398,40.0035 27.0178,40.0035
        L8.0178,40.0035
        L8.0178,52.0035
        Z">
    </path>
</svg>

(预览:https://i.imgur.com/nVnxcRg.png

我想要实现的是我有 3 个独立的渐变或填充空间:

  • 第一个是从内曲线到弯管(曲线)的中心。
  • 第二个是中心区域。
  • 从中心区域到管外曲线的第三个。

或者,我也可以使用具有多种停止颜色的单个渐变。

下图说明了想要的结果: https://i.imgur.com/oPEFAZT.png 在这种情况下,我添加的矩形说明了我想沿整条曲线使用的渐变。

我对 SVG 中的高级渐变进行了一些研究,但我无法理解如何应用它们,或者是否有必要这样做。 我了解如何将径向和线性渐变应用于矩形甚至曲线,但这并没有达到预期的效果。

我还发现了Can I apply a gradient along an SVG path?,它在管子中从左到右(可以这么说)创建了一个渐变,我希望它是从上到下的。

你们有什么办法解决这个问题吗?

【问题讨论】:

    标签: svg


    【解决方案1】:

    您可以通过使用带有模糊或光照的filters 来获得您想要的结果。这是一篇关于高级过滤器的好文章:https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/

    <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 150 150" >
        <defs>
            <filter id="filter1">
                <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blurOut" />
                <!-- We cut off the parts that overlap the source graphic… -->
                <feComposite operator="in" in="blurOut" in2="SourceAlpha" result="COMPOSITE"/>
                <!-- … and then merge source graphic and lighting effect: -->
                <feMerge>
                    <feMergeNode in="SourceGraphic" />
                    <feMergeNode in="COMPOSITE"/>
                </feMerge>
            </filter>
    
            <!-- https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/ -->
            <filter id="filter2">
                <!--We create a heightmap by blurring the source: -->
                <feGaussianBlur stdDeviation="5" in="SourceAlpha" result="BLUR"/>
                <!-- We then define a lighting effect with a point light that is positioned at virtual 3D coordinates x: 40px, y: -30px, z: 200px: -->
                <feSpecularLighting surfaceScale="6" specularConstant="1" specularExponent="30" lighting-color="#white" in="BLUR" result="SPECULAR">
                    <fePointLight x="40" y="40" z="2000" />
                </feSpecularLighting>
                <!-- We cut off the parts that overlap the source graphic… -->
                <feComposite operator="in" in="SPECULAR" in2="SourceAlpha" result="COMPOSITE"/>
                <!-- … and then merge source graphic and lighting effect: -->
                <feMerge>
                    <feMergeNode in="SourceGraphic" />
                    <feMergeNode in="COMPOSITE"/>
                </feMerge>
            </filter>
        </defs>
    
        <path stroke="white" stroke-width="20" fill="none" filter="url(#filter1)" 
              d="M-90,50 h150 a20,20 0 0,0 20,-20 v-150" />
    
        <path stroke="black" stroke-width="20" fill="none" filter="url(#filter2)" 
              d="M-40,100 h150 a20,20 0 0,0 20,-20 v-150" />
    </svg>

    【讨论】:

    • 对于未来的工作,我会记住这一点。现在我已经有几个已经使用渐变的“直”管道,当它连接到其他管道时,看起来弯曲的管道看起来很奇怪。我必须更改所有创建的管道以使用过滤器。不错的技巧。
    【解决方案2】:

    一般来说,不可能创建沿路径流动的渐变。

    但是,在像您这样只涉及直线段和圆弧的情况下,您可以通过将形状分解为这些部分来实现效果。然后对每个部分应用不同的渐变。您将&lt;linearGradient&gt; 用于直线部分,将&lt;radialGredient&gt; 用于弯曲部分。

    在下面的示例中,我为“管道”效果使用了一个非常简化的渐变。您可能希望为您的站点添加更多站点以提供更好的 3D 效果。

    <svg xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 57" 
        version="1.1" x="0px" y="0px">
        <defs>
          <linearGradient id="horizontalPipe" x2="0" y2="1">
            <stop offset="0" stop-color="white"/>
            <stop offset="0.25" stop-color="black"/>
            <stop offset="0.75" stop-color="black"/>
            <stop offset="1" stop-color="white"/>
          </linearGradient>
          <linearGradient id="verticalPipe">
            <stop offset="0" stop-color="white"/>
            <stop offset="0.25" stop-color="black"/>
            <stop offset="0.75" stop-color="black"/>
            <stop offset="1" stop-color="white"/>
          </linearGradient>
          <radialGradient id="curvedPipe" cx="0" cy="0" r="1">
            <stop offset="0.57" stop-color="white"/>
            <stop offset="0.677" stop-color="black"/>
            <stop offset="0.893" stop-color="black"/>
            <stop offset="1" stop-color="white"/>
          </radialGradient>
        </defs>
        
        <rect x="8" y="40" width="19" height="12" fill="url(#horizontalPipe)"/>
        <path d="M 27,40 A 16,16, 0,0,0 43,24 H 55 A 28,28, 0,0,1, 27,52 Z" fill="url(#curvedPipe)"/>
        <rect x="43" y="8" width="12" height="16" fill="url(#verticalPipe)"/>
    </svg>

    【讨论】:

    • 这看起来很棒。我想知道是否有 SVG 提案中指定的具有高级渐变的通用解决方案(我认为它与网格有关)。我试图弄清楚路径中的 SVG 命令如何与矩形相关,以及radialGradient 中的偏移量如何与路径相关。你有什么指点吗?
    • 径向渐变被定义为渐变的中心在左上角(cx=0,cy=0)。梯度中的偏移值基本上是百分比。第一个偏移的 0.57 值对应于比率 16(管道的内半径)与 28(外半径)。 16/28=0.57。所以梯度从外半径的 0.57 处开始。 0.677 和 0.893 分别对应于从 0.57 到 1.0(渐变结束和外半径)的距离的 0.25 和 0.75。
    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 2012-10-24
    • 1970-01-01
    相关资源
    最近更新 更多