2017-07-17 89 views
2

我在做和svg過濾與CSS動畫。我用與CSS轉換的SVG過濾器

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

filter:url('#goo'); 

集裝箱在CSS。

這裏是一個小提琴 https://codepen.io/sergey_mell/pen/MoRMwR

而且我被困到下一個問題。動畫看起來像是在一些盒子裏面進行的(它的大小似乎取決於最初的動畫狀態大小)。 任何人都可以幫助我避免這種情況嗎?

回答

2

SVG濾鏡具有一個定義的「濾鏡區域」,其中應用了效果。這是因爲某些操作可能非常緩慢(例如高斯模糊),並且您通常希望限制它們的計算面積。

濾波器的默認濾波器區域是:

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

換句話說,被過濾的元件,加圍繞它的外部的10%的邊界。該區域外的任何內容都將被裁剪(並且不可見)。

解決方法是增加過濾器區域,使其包含所有的斑點。因此,舉例來說,如果我們將保證金增加到50%,

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

它現在可以正常工作。

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"/> 
 
    \t </filter> 
 
    </defs> 
 
</svg>

1

我實際上是由它通過設置工作width/height.blobs容器:

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

你也許可以找到你所需要的最大大小,它設置爲,而不是500

+0

感謝您的幫助和快速回答! 我也找到了解決方案。然而,對我來說這似乎不太合適,因爲我不知道容器的大小,所以設置一些非常大的值或用容器蓋住整個身體似乎不好...... –

1

如果你沒有明確規定一個被替換的元素(img,svg等),那麼瀏覽器會給它一個300px x 150px的默認大小(或者接近的東西)。如果你不知道尺寸,那麼你需要通過JavaScript來設置它,如果你需要確切的像素,或者100%,如果你想要填充它的包含元素,則需要100%。

+0

非常感謝。我會試一試 –