有什么方法可以应用具有特定形状的svg过滤器?

时间:2019-06-06 22:46:38

标签: html css animation svg

我正在实验svg滤镜以获得漂亮的动画和效果。我刚刚发现了一个新世界,但是我面临一个问题。 我正在尝试重现这种效果:https://www.youtube.com/watch?v=GcSU4xH6_Ro
我不知道如何复制变形的圆。

我知道我可以使用过滤器和svg,但实际上,如果我将svg过滤器应用到框中,则所有div都会受到影响,而不是这个圆圈。

我想知道是否可以使svg像“镜头”一样 如果您想查看代码,我做了一个jsFiddle:https://jsfiddle.net/wekhz7rb/

我只想使用CSS

    <div class="box">
    <svg class="svg" xmlns="http://www.w3.org/2000/svg" id="effect"     
     width="275px" height="275px">
    <filter id="noise">
    <feTurbulence baseFrequency="0.05" numOctaves="2" result="noise">    
    </feTurbulence>
    <feComposite operator="in" in2="SourceGraphic"></feComposite>
    <feDisplacementMap in="SourceGraphic" in2="noise" scale="50">        
    </feDisplacementMap>
    </filter>
    <!-- <circle cx="137" cy="137" r="137" fill="red" filter="url(#noise)">            
    </circle> -->
    </svg>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    <div class="text">DREAMS</div>
    </div>
    @import url(//fonts.googleapis.com/css?family=Archivo+Black);
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      background-color: #7427FF;
      height: 100vh;
      width: 100vw;
    }
    .box {
      height: 550px;
      width: 550px;
      position: relative;
      overflow: hidden;
      text-align: center;
      filter: url(#noise); 
   // mask: url(#effect);
    }
    .svg {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateY(-50%) translateX(-50%);
    z-index: 10;
    }

.text {
  font-family: 'Archivo Black', sans-serif;
  display: inline-block;
  font-size: 116px;
  line-height: 90px;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 0;
  background: linear-gradient(0deg, rgba(117,62,255,1) 0%, 
   rgba(249,37,166,1) 40%, rgba(246,154,180,1) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation-name: translate;
  animation-timing-function: linear;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  animation-fill-mode: backwards;

@for $i from 1 through 16 {
    &:nth-child(#{$i}) {
      animation-delay:  #{$i * 1}s
    }
  }
}

@keyframes translate {
  from {
     transform: translateY(-90px) translateZ(0)
  }
  to {
      transform: translateY(555px) translateZ(0)
  }
}

1 个答案:

答案 0 :(得分:0)

是的,这是可能的。阅读feDisplacementMap的工作原理。

https://www.w3.org/TR/SVG11/single-page.html#filters-feDisplacementMapElement

所有要做的就是确保圆外的像素导致位移0。为此,颜色通道值必须为0.5(128)。

因此,如果您的X通道是红色通道,Y通道是绿色通道,那么将圆外的区域设置为50%黄色(即#808000),应导致位移为零。

更新:feDisplacementMap的工作原理

feDisplacement的工作原理是,它从“位移图”(in2)中获取像素值,并使用该像素的颜色通道来确定in图像中其他位置的位置顶部复制一个像素。

例如,假设我们当前正在查看像素(100,200)。

  • 查看in2中(100,200)处的像素
  • 确定位移偏移量。可以说是(-0.4,0.5)。稍后我们将看到如何获取这些值。
  • 将偏移量乘以scale。如果小数位数为10,则新的偏移量将为(-4,5)
  • 获取100 - 4中(200 - 5in)处的像素
  • 在输出(result)中将该像素值写为(100,200)。

计算偏移量

首先查看in2像素中的适当颜色通道(R,G,B或A)。通过使用xChannelSelectoryChannelSelector属性来设置用于X和Y偏移的颜色通道。

这些通道中的每个通道的值都可以在0到255之间。对于R通道,0表示无红色,而255表示全红色。为了进行偏移量计算,将0..255范围转换为0..1范围。

+----------------------+------+------------+
| Colour channel value | XC() | XC() - 0.5 |
+----------------------+------+------------+
|        0  (00)       |  0   |    -0.5    |
|       26  (1A)       |  0.1 |    -0.4    |
|      128  (80)       |  0.5 |     0      |
|      255  (FF)       |  1   |     0.5    |
+----------------------+------+------------+

因此,如果xChannelSelector="R"yChannelSelector="G",则我们的#1AFF00in2的像素值将导致我们使用的位移偏移为(-0.4,0.5)以上。

返回特定形状的位移图

从以上内容,希望您可以看到,如果in2像素通道的值为128,则将导致零偏移。这意味着result中的输出像素将直接从输入(in)中的相同位置复制过来。

因此要创建具有圆形边界的地图。您要做的就是使所有像素都位于圆圈128之外。

feDisplacementMap 的问题

最近几年进行了一些更改,以防止与feDisplacementMap相关的某些安全问题,这意味着现在可能很难使用。 该过程中仍然存在一些错误。例如:https://bugs.chromium.org/p/chromium/issues/detail?id=798001

加上feImage的错误:例如。 https://bugzilla.mozilla.org/show_bug.cgi?id=455986

您可能需要在feImage上使用外部图像,并确保Web服务器上的CORS设置正确。

或者将数据URL与feImage一起使用似乎可以。参见this CodePen from @enxaneta

希望这会有所帮助。