简体   繁体   English

具有CSS过渡的SVG过滤器

[英]SVG filter with CSS transitions

I was doing and svg filter with css animation. 我正在用css动画做svg过滤器。 I use 我用

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <filter id="goo">
      <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
      <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7" result="goo" />
      <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
   </filter>
 </defs>
</svg>

and

filter:url('#goo');

for container in CSS. 用于CSS中的容器。

Here is a fiddle https://codepen.io/sergey_mell/pen/MoRMwR 这是一个小提琴https://codepen.io/sergey_mell/pen/MoRMwR

And I got stuck into next issue. 我陷入了下一个问题。 The animation appears to be carrying out like inside some box (it's size seems to be depend on initial animation state size). 动画似乎在一些框内执行(它的大小似乎取决于初始动画状态大小)。 Can anybody help me to avoid this? 任何人都可以帮我避免这种情况吗?

SVG filters have a defined "filter region", inside which the effects are applied. SVG过滤器具有定义的“过滤区域”,其中应用了效果。 This is because some operations can be very slow (eg. gaussian blur) and you generally want to limit the area over which they are calculated. 这是因为某些操作可能非常慢(例如高斯模糊),并且您通常希望限制计算它们的区域。

The default filter region of a filter is: 过滤器的默认过滤器区域是:

x="-10%" y="-10%" width="120%" height="120%"

In other words, the element being filtered, plus a 10% border around the outside of it. 换句话说,被过滤的元素,以及围绕其外部的10%边界。 Anything outside that area will be clipped (and invisible). 该区域之外的任何东西都将被剪裁(并且不可见)。

The solution is to increase the filter region so that it encompasses all of your blobs. 解决方案是增加过滤器区域,使其包含所有blob。 So, for example, if we increase the margin to 50% 所以,例如,如果我们将保证金增加到50%

<filter id="goo" x="-50%" y="-50%" width="200%" height="200%">

it now works properly. 它现在正常工作。

 body{ background:white; background-image:url(https://i.imgur.com/d47ZIU3.jpg); background-size:cover; } .blobs{ filter:url('#goo'); position:absolute; top:100px; left:200px; } @keyframes blob-left-top-anim{ 0%{ transform:scale(1.1) translate(0,0); } 33%{ transform:scale(0.9) translate(-65px,0); } 62%{ transform:scale(0.7) translate(-65px,-65px); } 94%{ transform:scale(1.1) translate(0,0); } } @keyframes blob-right-top-anim{ 0%{ transform:scale(1.1) translate(0,0); } 33%{ transform:scale(0.9) translate(65px,0); } 64%{ transform:scale(0.7) translate(65px,-65px); } 96%{ transform:scale(1.1) translate(0,0); } } @keyframes blob-left-bottom-anim{ 0%{ transform:scale(1.1) translate(0,0); } 33%{ transform:scale(0.9) translate(-65px,0); } 66%{ transform:scale(0.7) translate(-65px,65px); } 98%{ transform:scale(1.1) translate(0,0); } } @keyframes blob-right-bottom-anim{ 0%{ transform:scale(1.1) translate(0,0); } 33%{ transform:scale(0.9) translate(65px,0); } 68%{ transform:scale(0.7) translate(65px,65px); } 100%{ transform:scale(1.1) translate(0,0); } } .blob{ position:absolute; background:#e97b7a; left:50%; top:50%; width:100px; height:100px; line-height:100px; text-align:center; color:white; font-size:40px; border-radius:100%; margin-top:-50px; margin-left:-50px; animation:blob-left-top-anim cubic-bezier(0.770, 0.000, 0.175, 1.000) 4s infinite; } .blob:nth-child(2){ animation-name:blob-right-top-anim; } .blob:nth-child(3){ animation-name:blob-left-bottom-anim; } .blob:nth-child(4){ animation-name:blob-right-bottom-anim; } 
 <div class="blobs"> <div class="blob">4</div> <div class="blob">3</div> <div class="blob">2</div> <div class="blob">1</div> </div> <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <filter id="goo" x="-50%" y="-50%" width="200%" height="200%"> <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" /> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo" /> <feComposite in="SourceGraphic" in2="goo" operator="atop"/> </filter> </defs> </svg> 

I actually made it work by setting a width / height to the .blobs container: 我实际上通过设置.blobs容器的width / height来实现.blobs

.blobs{
  filter:url('#goo');
  position:absolute;
  top:100px;
  left:200px;
  width: 500px;
  height: 500px;
}

You can probably find out the max size you need and set it to that instead of 500. 您可以找出所需的最大尺寸,并将其设置为500而不是500。

If you do not explicitly size a replaced element (img, svg etc.) then the browser gives it a default size of 300px x 150px (or something close). 如果你没有明确地确定替换元素(img,svg等)的大小,那么浏览器会给它一个默认大小为300px x 150px(或接近的东西)。 If you don't know the size then you need to set it via javascript if you need exact pixels, or 100%, 100% if you want it to fill its containing element. 如果你不知道大小,那么你需要通过javascript设置它,如果你需要精确像素,或100%,100%,如果你想要它填充其包含元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM