【问题标题】:Displacement map filter not working on rotated object置换贴图过滤器不适用于旋转对象
【发布时间】:2020-02-07 15:10:22
【问题描述】:

我正在尝试制作镜像模式,但是当我添加置换滤镜时,它似乎只适用于第一和第四象限。我是否忽略了一些初学者错误或这种行为是预期的?

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

【问题讨论】:

    标签: svg svg-filters


    【解决方案1】:

    在您的过滤器中,我为feDisplacementMap 添加了xChannelSelector="R"。我用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>

    另外,我会将过滤器应用于&lt;symbol&gt; 内的&lt;rect&gt;,而不是将其应用于组。

    【讨论】:

    • 哇,它有效。过滤器必须应用于整体,否则边缘会出现锯齿状过渡,这样一切都是连续的。通道选择器适用于除默认 A 以外的 andy 值(适用于所有其他填充,而不仅仅是红色)。我没有得到什么,要么没有阿尔法,然后不应该发生位移,要么有阿尔法,所有的象限都应该被位移。为什么不是这样?
    【解决方案2】:

    您只是缺少 xChannelSelector 或 yChannelSelector - 其中一个是必需的。

    (更新-正如您在评论中提到的那样,当您将其省略时,它默认使用 X 和 Y 中的 Alpha 通道-因此它将在顶部/左下/右对角轴上上下移动所有内容-因此具有此方向的纯色对角线只会在其起点和终点显示扭曲)。

    如果您在生成 feTurbulence 后不打算以某种方式对其进行处理,则任何一个通道 (RGBA) 都可以用作位移源 - 因为 Perlin 噪声在所有四个通道中的噪声相同。

    (您不需要使用 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>

    【讨论】:

    • 我查看了规格,ChannelSelector 是可选的,默认为 A。当它击中我时,尝试用位图替换符号并旋转它时,我会稍作修改。 SVG 坐标是从左上角开始的,当你用相同的值替换像素时(因为 X 和 Y 默认为相同的 A 值),它将在对角线上移动,所以当像素实际被替换时,对角线仍然主要保持不变。指定不同的通道选择器可以解决这个问题。接受作为答案,因为您向我暗示了正确的方向。
    猜你喜欢
    • 2017-10-12
    • 2021-02-23
    • 2021-09-05
    • 2019-04-18
    • 2012-03-04
    • 1970-01-01
    • 2012-06-03
    • 2021-07-07
    • 1970-01-01
    相关资源
    最近更新 更多