Фильтр карты смещения не работает на повернутом объекте - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь создать зеркальный рисунок, но когда я добавляю фильтр смещения, кажется, он работает только на первом и четвертом квадранте. Я пропускаю какую-то ошибку новичка или такое поведение ожидается?

<svg width="500px" height="500px">
    <defs>
        <clipPath id="clip">
          <rect x="0" y="0" width="50%" height="50%"/>
        </clipPath>

        <pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"  patternTransform="scale(20) rotate(0)">
          <path d="M-1,1 l2,-2
                 M0,4 l4,-4
                 M3,5 l2,-2"
              style="stroke:red; stroke-width:1" />
        </pattern>

        <symbol id="quarter">
          <rect x="0" y="0" width="100%" height="100%" fill="url(#diagonalHatch)" clip-path="url(#clip)"/>
        </symbol>

        <filter id="noise" x="0%" y="0%" width="100%" height="100%">
                <feTurbulence baseFrequency="0.02" numOctaves="3" result="noise" seed="3" />
                <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" />
        </filter>
    </defs>


    <g filter="url(#noise)">
      <use xlink:href="#quarter"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(90)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(180)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(270)"/>
    </g>
</svg>

Ответы [ 2 ]

2 голосов
/ 10 октября 2019

В вашем фильтре я добавил xChannelSelector="R" для feDisplacementMap. Я использую R для красного, так как ваши фигуры красные.

    <filter id="noise" x="0%" y="0%" width="100%" height="100%">
            <feTurbulence baseFrequency="0.02" numOctaves="3" result="noise" seed="3" />
            <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" xChannelSelector="R" />
    </filter>

<svg width="500px" height="500px">
    <defs>
        <clipPath id="clip">
          <rect x="0" y="0" width="50%" height="50%"/>
        </clipPath>

        <pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"  patternTransform="scale(20) rotate(0)">
          <path d="M-1,1 l2,-2
                 M0,4 l4,-4
                 M3,5 l2,-2"
              style="stroke:red; stroke-width:1" />
        </pattern>

        <symbol id="quarter">
          <rect x="0" y="0" width="100%" height="100%" fill="url(#diagonalHatch)" clip-path="url(#clip)"/>
        </symbol>

        <filter id="noise" x="0%" y="0%" width="100%" height="100%">
                <feTurbulence baseFrequency="0.02" numOctaves="3" result="noise" seed="3" />
                <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" xChannelSelector="R" />
        </filter>
    </defs>


    <g filter="url(#noise)">
      <use xlink:href="#quarter"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(90)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(180)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(270)"/>
    </g>
</svg>

Также я бы применил фильтр к <rect> внутри <symbol> вместо применения к группе.

1 голос
/ 11 октября 2019

Вам просто не хватает xChannelSelector или yChannelSelector - один из которых необходим.

(Обновление - как вы упомянули в комментарии, когда вы пропускаете это, по умолчанию используется альфа-канал как в X, так и в Y - поэтому он будет смещать все вверх и вниз вверх / влево, вниз / вправодиагональная ось - поэтому сплошные цветные диагональные линии с такой ориентацией будут показывать искажения только на их начальных и конечных кромках).

Если вы не собираетесь каким-либо образом обрабатывать feTurbulence после его генерации, тогда любойканалов (RGBA) работает как источник смещения - поскольку шум Перлина одинаково шумит во всех четырех каналах.

(Вам не нужно использовать канал R, потому что ваши фигуры красного цвета - это наоборот - селектор каналов применяется к вашему входу шума, а не к той форме, к которой вы хотите применить его.)

<svg width="500px" height="500px">
    <defs>
        <clipPath id="clip">
          <rect x="0" y="0" width="50%" height="50%"/>
        </clipPath>

        <pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"  patternTransform="scale(20) rotate(0)">
          <path d="M-1,1 l2,-2
                 M0,4 l4,-4
                 M3,5 l2,-2"
              style="stroke:red; stroke-width:1" />
        </pattern>

        <symbol id="quarter">
          <rect x="0" y="0" width="100%" height="100%" fill="url(#diagonalHatch)" clip-path="url(#clip)"/>
        </symbol>

        <filter id="noise" x="0%" y="0%" width="100%" height="100%">
                <feTurbulence baseFrequency="0.02" numOctaves="3" result="noise" seed="3" />
                <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" xChannelSelector="R" yChannelSelector="G"/>
        </filter>
    </defs>


    <g filter="url(#noise)">
      <use xlink:href="#quarter"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(90)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(180)"/>
      <use xlink:href="#quarter" style="transform-origin: 50% 50%;" transform="rotate(270)"/>
    </g>
</svg>
...