Есть ли способ повернуть шаблон feImage или feTile в SVG? - PullRequest
0 голосов
/ 23 октября 2018

В этом примере я настроил фильтр, который текстурирует данный элемент шаблоном шахматной доски, используя эффекты фильтра 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 голосов
/ 24 октября 2018

Теоретически, вы могли бы сделать это с помощью 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>
0 голосов
/ 30 октября 2018

Я понял это.Вам нужно обернуть изображение в несколько вложенных <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>
0 голосов
/ 23 октября 2018

Другое решение будет использовать шаблон 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>

ОБНОВЛЕНИЕ

на этот раз я использую изображение SVUR 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>
...