是否可以使用更少的路径来实现相同的效果?

时间:2017-01-30 15:57:42

标签: svg

考虑this fiddle

SVG Speech bubble

我有相同的路径5次,以便我可以对它执行一些过滤器:

<svg xmlns="http://www.w3.org/2000/svg" width="649" height="173" viewBox="0 0 649 173">

  <!-- paths -->
  <path class="cls-3" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#blur3)" />
  <path class="cls-3" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#blur3)" />
  <path class="cls-2" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#blur2)" />
  <path class="cls-2" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#blur2)" />
  <path class="cls-1" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#blur1)" />

  <!-- filters -->
  <filter id="blur1">
    <feGaussianBlur in="SourceGraphic" stdDeviation="0" />
  </filter>
  <filter id="blur2">
    <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    <feMorphology operator="dilate" radius="1" />
  </filter>
  <filter id="blur3">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
    <feMorphology operator="dilate" radius="3" />
  </filter>
</svg>

我宁愿拥有一条带有复杂滤镜的路径。从MDN的文档来看,我应该能够做到这一点,但我不清楚如何。

额外信息

MDN文档提供了以下示例:

<svg width="120" height="120"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">

  <filter id="dropShadow">
    <feGaussianBlur in="SourceAlpha" stdDeviation="3" />
    <feOffset dx="2" dy="4" />
    <feMerge>
        <feMergeNode />
        <feMergeNode in="SourceGraphic" />
    </feMerge>
  </filter>

  <circle cx="60"  cy="60" r="50" fill="green"
          filter="url(#dropShadow)" />
</svg>

这给出了以下结果:

enter image description here

正如您所看到的,这实现了多个没有多个路径的层。

2 个答案:

答案 0 :(得分:1)

这应该是一个或两个路径绝对可能。要获取过滤器的代码,我真的建议您使用Inkscape。我提供了一个过滤器编辑器,专门用于创建复杂的过滤器。过滤器编辑器的接口是按照SVG过滤器的工作方式设计的,因此您可以通过某种方式将一个输出插入另一个过滤器的输入。

简单的阴影滤镜在编辑器窗格中可能如下所示: example

因此,这是建模和理解svg过滤器的一种非常好的方法。

我希望我能提供帮助。

<强>更新

结果如下:

enter image description here

这些过滤器的完整和完整的解释以及如何组装这些过滤器的方法远远超出了答案的范围,但是我发现这本书非常有用的好书可能是that。< / p>

更新#2

最好的方法是:在inkscape中保存后,您可以打开创建的文件并查看生成的过滤器的来源,在最好的情况下,复制和粘贴是您的朋友。 ;)

答案 1 :(得分:0)

Got it.

“好的,但如何?”

首先#blur1没用,正如@ robert-longson所指出的那样:

<filter id="blur1"><filter id="blur1">
    <feGaussianBlur in="SourceGraphic" stdDeviation="0" />
</filter>

0的高斯模糊是相同的图像。杜!

接下来,我只是看了一下当我重复路径并找到相关的SVG过滤器时我想要做的事情:

  • 我想要一种新颜色 - feFlood
  • 我希望它变得模糊 - feGaussianBlur
  • 我希望它能够扩展一点 - feMorphology

最后,经过一段时间的游戏,我得到了它的工作:

<svg xmlns="http://www.w3.org/2000/svg" width="649" height="173" viewBox="0 0 649 173">
  <def>
    <style>
      .cls-1 {
        fill: #D4DEF8;
        fill-rule: evenodd;
      }

      .cls-2 {
        fill: #6ACDFD;
        fill-rule: evenodd;
      }

      .cls-3 {
        fill: #0030DB;
        fill-rule: evenodd;
      }
    </style>
  </def>

  <path class="cls-1" d="M69,35H595a20,20,0,0,1,20,20V80a20,20,0,0,1-20,20H69A20,20,0,0,1,49,80V55A20,20,0,0,1,69,35Zm477,65s-4.027,26.227,44,44c0.254,0.094-30.858-26.75-14-44C576.221,99.774,546,100,546,100Z" filter="url(#glow)" />

  <filter id="glow">
    <feGaussianBlur stdDeviation="2.5" result="coloredBlur"/>

    <!-- First glow -->
    <feFlood result="flood1" flood-color="#6ACDFD" floodOpacity="1"></feFlood>
    <feComposite in="flood1" result="mask1" in2="SourceGraphic" operator="in"></feComposite>
    <feMorphology in="mask1" result="dilated1" operator="dilate" radius="1"></feMorphology>
    <feGaussianBlur in="dilated1" result="blurred1" stdDeviation="2"></feGaussianBlur>

    <!-- Second glow -->
    <feFlood result="flood2" flood-color="#0030DB" floodOpacity="1"></feFlood>
    <feComposite in="flood2" result="mask2" in2="SourceGraphic" operator="in"></feComposite>
    <feMorphology in="mask2" result="dilated2" operator="dilate" radius="5"></feMorphology>
    <feGaussianBlur in="dilated2" result="blurred2" stdDeviation="3"></feGaussianBlur>

    <!-- Pop em in -->
    <feMerge>
        <feMergeNode in="blurred2"></feMergeNode>
        <feMergeNode in="blurred1"></feMergeNode>

        <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>

</svg>

enter image description here

“哇,很好。”

感谢。要记住的一些事情:

  • 跟踪您的inresult值 - 这些是您如何相互“管道”过滤器。具体来说,in可让您指定应将过滤器应用于何处,result是您为过滤器结果指定的名称。
  • 这些过滤器的顺序(显然)非常重要
  • 使用feMergefeMergeNode将过滤器“合并”到最终渲染中