有没有办法在SVG中旋转feImage或feTile模式?

时间:2018-10-23 14:56:04

标签: image svg svg-filters

在此示例中,我设置了一个滤镜,该滤镜使用SVG滤镜效果通过棋盘图案对给定元素进行纹理处理:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  
  <defs>
    <filter id="texture" x="0" y="0" width="100%" height="100%">
      <feImage width="16" height="16" result="checkerboard-image"
               xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEXMzMzLy8v////+/v7l
9thZAAAAO0lEQVR4ASXIUQ3AIBAFsJKcACQxu4/kBCAJFUu2ftbUYeWYI8G51kqU3VSCm68l
hpyH/nuWHaQH2eoF1bMYGK3LF0IAAAAASUVORK5CYII="/>
      <feTile in="checkerboard-image" result="texture" />
      <feBlend in="SourceGraphic" in2="texture" mode="multiply" />
      <feTile/>
    </filter>
  </defs>

  <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"
      x="0" y="0" width="100%" height="100%" style="filter:url(#texture);"/>
</svg>

有没有一种方法可以旋转整个纹理,以便得到例如在同一张图片上应用45度旋转的棋盘图案?

3 个答案:

答案 0 :(得分:3)

我知道了。您需要将图像包装在几个嵌套的<g>组中。在最里面的组中:

  1. 以负的期望角度旋转图像
  2. 应用过滤器
  3. 以所需的正角度旋转图像

图像将保持原始旋转,但是效果将应用于旋转后的图像,从而使效果本身旋转。

这是代码本身:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  
  <defs>
    <filter id="texture" x="0" y="0" width="100%" height="100%">
      <feImage width="16" height="16" result="texture-image"
               xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEXMzMzLy8v////+/v7l
9thZAAAAO0lEQVR4ASXIUQ3AIBAFsJKcACQxu4/kBCAJFUu2ftbUYeWYI8G51kqU3VSCm68l
hpyH/nuWHaQH2eoF1bMYGK3LF0IAAAAASUVORK5CYII="/>
      <feTile in="texture-image" result="texture" />
      <feBlend in="SourceGraphic" in2="texture" mode="multiply" />
      <feTile/>
    </filter>
  </defs>

  
  <g transform="rotate(30)">
    <g filter="url(#texture)" >
      <g transform="rotate(-30)">
        <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" x="0" y="0" width="100%" height="100%"/>
      </g>
    </g>
  </g>
</svg>

答案 1 :(得分:2)

另一个解决方案是使用SVG模式,如下所示:

<svg viewBox='0 0 200 200' width='200' height='200' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
  <defs>
    <pattern id='_texture' width='16' height='16' patternUnits='userSpaceOnUse'  patternTransform="rotate(45)">
      <g fill='rgba(0,0,0,.3)'>
        <rect width='8' height='8'/>
        <rect x='8' y='8' width='8' height='8'/>
      </g>
    </pattern>
  </defs> 
  
  
  <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"
      x="0" y="0" width="100%" height="100%" />
  
  <rect width='100%' height='100%' fill='url(#_texture)'/>
</svg>

更新

这次,我使用的是SVG dataURI图像而不是您的dataURI。过滤器仍然在那里。希望对您有所帮助。

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"> 
  <defs>
    <filter id="texture" x="0" y="0" width="100%" height="100%">
      <feImage width="11.31" height="11.31" result="checkerboard-image"
               xlink:href="data:image/svg+xml,%3Csvg viewBox='0 0 11.31 11.31' width='11.31' height='11.31' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg fill='rgba(0,0,0,.3)' transform='rotate(45 5.655 5.655)'%3E%3Crect width='8' height='8' x='1.655' y='1.655'/%3E%3C/g%3E%3C/svg%3E"/>
      <feTile in="checkerboard-image" result="texture" />
      <feBlend in="SourceGraphic" in2="texture" mode="multiply" />
      <feTile/>
    </filter>
  </defs>

  <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"
      x="0" y="0" width="100%" height="100%" style="filter:url(#texture);"/>
</svg>

答案 2 :(得分:2)

从理论上讲,您可以使用feDisplacementMap做到这一点,但是生成正确的位移图非常困难,因此,实际上,您必须在滤镜外旋转棋盘格(通过重做棋盘格图像,或使用patternTransform)。这是一个反转过滤器输入的示例-它通过feImage提取主图像,并使旋转的棋盘成为SourceGraphic。

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  
  <defs>
    <pattern id="checker-pattern" x="0" y="0" width="16" height="16" patternTransform="rotate(45) translate(-4 4)" patternUnits="userSpaceOnUse">
      <image x="0" y="0" height="16" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEXMzMzLy8v////+/v7l9thZAAAAO0lEQVR4ASXIUQ3AIBAFsJKcACQxu4/kBCAJFUu2ftbUYeWYI8G51kqU3VSCm68l
hpyH/nuWHaQH2eoF1bMYGK3LF0IAAAAASUVORK5CYII="/>
    </pattern>
    
    
    <filter id="texture" x="0" y="0" width="100%" height="100%">
      <feImage x="0%" y="0%" width="100%" height="100%" result="original-image"
xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"/>
      <feBlend in="SourceGraphic" mode="multiply" />
    </filter>
  </defs>
<g filter="url(#texture)">
  <rect x="0%" y="0%" width="100%" height="100%" fill="url(#checker-pattern)"/>
  </g>
</svg>