滤镜效果

在某些情况下,基本形状无法提供您实现某些效果所需的灵活性。例如,要创建合理的投影效果,就不能简单地使用渐变组合。滤镜是 SVG 创建复杂效果的机制。

一个基本的例子是为 SVG 内容添加模糊效果。虽然可以使用渐变来实现基本的模糊,但要实现更高级的模糊效果,则需要使用模糊滤镜。

示例

滤镜由 <filter> 元素定义,该元素应放置在 SVG 文件的 <defs> 部分中。在滤镜标签之间是一系列的基本运算:建立在先前运算基础上的基本操作(如模糊、添加灯光效果等)。要将创建的滤镜应用于图形元素,请设置 filter 属性。

html
<svg
  width="250"
  viewBox="0 0 200 85"
  xmlns="http://www.w3.org/2000/svg"
  version="1.1">
  <defs>
    <!-- Filter declaration -->
    <filter
      id="MyFilter"
      filterUnits="userSpaceOnUse"
      x="0"
      y="0"
      width="200"
      height="120">
      <!-- offsetBlur -->
      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />
      <feOffset in="blur" dx="4" dy="4" result="offsetBlur" />

      <!-- litPaint -->
      <feSpecularLighting
        in="blur"
        surfaceScale="5"
        specularConstant=".75"
        specularExponent="20"
        lighting-color="#bbbbbb"
        result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000" />
      </feSpecularLighting>
      <feComposite
        in="specOut"
        in2="SourceAlpha"
        operator="in"
        result="specOut" />
      <feComposite
        in="SourceGraphic"
        in2="specOut"
        operator="arithmetic"
        k1="0"
        k2="1"
        k3="1"
        k4="0"
        result="litPaint" />

      <!-- merge offsetBlur + litPaint -->
      <feMerge>
        <feMergeNode in="offsetBlur" />
        <feMergeNode in="litPaint" />
      </feMerge>
    </filter>
  </defs>

  <!-- Graphic elements -->
  <g filter="url(#MyFilter)">
    <path
      fill="none"
      stroke="#D90000"
      stroke-width="10"
      d="M50,66 c-50,0 -50,-60 0,-60 h100 c50,0 50,60 0,60z" />
    <path
      fill="#D90000"
      d="M60,56 c-30,0 -30,-40 0,-40 h80 c30,0 30,40 0,40z" />
    <g fill="#FFFFFF" stroke="black" font-size="45" font-family="Verdana">
      <text x="52" y="52">SVG</text>
    </g>
  </g>
</svg>

步骤 1

html
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />

<feGaussianBlur> 获取 in "SourceAlpha",它是源图形的 alpha 通道;应用 4 的模糊;并将 result 存储在名为 "blur" 的临时缓冲区中。

步骤 2

html
<feOffset in="blur" dx="4" dy="4" result="offsetBlur" />

<feOffset> 获取 in "blur",我们之前创建的;将结果 "4" 向右移动,并将 "4" 向下移动;并将 result 存储在缓冲区 "offsetBlur" 中。这两个基本运算刚刚创建了一个投影。

步骤 3

html
<feSpecularLighting
  in="offsetBlur"
  surfaceScale="5"
  specularConstant=".75"
  specularExponent="20"
  lighting-color="#bbbbbb"
  result="specOut">
  <fePointLight x="-5000" y="-10000" z="20000" />
</feSpecularLighting>

<feSpecularLighting> 获取 in "offsetBlur",生成灯光效果,并将 result 存储在缓冲区 "specOut" 中。

步骤 4

html
<feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut" />

第一个 <feComposite> 获取 in "specOut" 和 "SourceAlpha",屏蔽 "specOut" 的结果,以便结果不超过 "SourceAlpha"(原始源图形),并覆盖 result "specOut"。

步骤 5

html
<feComposite
  in="SourceGraphic"
  in2="specOut"
  operator="arithmetic"
  k1="0"
  k2="1"
  k3="1"
  k4="0"
  result="litPaint" />

第二个 <feComposite> 获取 in "SourceGraphic" 和 "specOut",将 "specOut" 的结果添加到 "SourceGraphic" 的顶部,并将 result 存储在 "litPaint" 中。

步骤 6

html
<feMerge>
  <feMergeNode in="offsetBlur" />
  <feMergeNode in="litPaint" />
</feMerge>

最后,<feMerge> 将 "offsetBlur"(投影)和 "litPaint"(带有灯光效果的原始源图形)合并在一起。

Source graphic

源图形

Primitive 1

基本运算 1

Primitive 2

基本运算 2

Primitive 3

基本运算 3

Primitive 4

基本运算 4

Primitive 5

基本运算 5

Primitive 6

基本运算 6