Search code examples
imagesvgsvg-filters

Is there a way to rotate feImage or feTile pattern in an SVG?


In this example, I set up a filter that textures the given element with a checkboard pattern using SVG filter effects:

<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>

Is there a way I can rotate the whole texture, so that I get e.g. a 45-degree rotated checkboard pattern applied on the same image?


Solution

  • I figured it out. You need to wrap the image in several nested <g> groups. From the innermost group:

    1. Rotate the image in the negative desired angle
    2. Apply the filter
    3. Rotate the image in the positive desired angle

    The image will remain in the original rotation, but the effect will have been applied on the rotated image, thus making the effect itself rotated.

    Here's the code itself:

    <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>