CSS animation で遊び倒す　- 涙-   Gooey Effect with SVG filter


CSS animation day15 となりました。

前回、[涙](https://qiita.com/duka/items/a2dd3dc9c33b6750fe8a) を作りましたが、背景画像との相性が悪く、Codepen の作品が変になってしまいました。Gooey Effect をつけた背景と、background 画像が、お互いに干渉していたせいです。

ということで、本日は、SVGを使って、涙に再挑戦したいと思います。


#1. 完成版
![ダウンロード (34).gif](https://qiita-image-store.s3.amazonaws.com/0/232715/2590cc1a-dec2-9136-87c1-3e88bc334ce5.gif)

#2. 参考文献
[CSS trick](https://css-tricks.com/gooey-effect/)
[THE ORTHODOX WORKS](https://theorthodoxworks.com/study/css-filter-gooey-effect-and-svg/)
[SVG1.1](https://triple-underscore.github.io/SVG11/filters.html#Introduction)
[codorops](https://tympanus.net/codrops/2015/03/10/creative-gooey-effects/) (かなりわかりやすいです！)
#3. SVG filter を学ぶ

❶. 

CSS で通常の画像をぼかしたい時、filter: blur() でbackground を操作すれば、簡単にできました。([前回記事、最下部参照](https://qiita.com/duka/items/108f5a32181920ae2972))
では、SVG画像 をぼかしたいなと思ったら、どうしたら良いでしょうか？　

・・・

SVGでは、[原始フィルター](https://triple-underscore.github.io/SVG11/filters.html#Introduction)と呼ばれるものを、子要素にセットして、filter プロパティと一緒に使う必要があります。

原始フィルター要素とはたくさんあるので、[こちら]()を参照頂きたいのですが、よく使うものを抜粋すると

>
ぼかしたい時: feGaussianBlur
色を変えたい時: feColorMatrix 
画像を合体したい時: feBlend

などあります。実際のコードを見てみましょう。
<br/>
⑴　feGaussianBlur 

```index.html
 <filter id="filter">
     <feGaussianBlur
        in="SourceGraphic"
        stdDeviation="20"
        result="blur"
      />
 </filter>
```

__in = "SourceGraphic"__ で、フィルターが適用されるターゲット要素(画像、図形など)をグラフィック内容として利用しますよ、と宣言します。

__stdDeviation="20"__ で、std(standard)に、 X軸、Y軸へ20px のblurをつけますよ、と宣言します。そして、結果をblurと名付けます。


![ダウンロード (32).gif](https://qiita-image-store.s3.amazonaws.com/0/232715/023a5328-4388-4e19-d6fe-03a11836e46b.gif)

上の画像の変化が、feDaussianBlur の効果です。
<br/>
⑵ feColorMatrix

```index.html
 <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="filter"
 />
```

__in = "blur"__ で、先ほどのfeGaussianBlur の結果へ、色の設定を加えますよと宣言してます。

matrix、values については、[こちらの記事](http://java-lang-programming.com/ja/articles/87) ご一読ください。

<img width="307" alt="スクリーンショット 2019-02-04 10.54.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/232715/43ccf7d1-70d8-e941-9d1d-361db68eabd8.png">

カラーマトリクスで大事なのは、最後の2つの数字です。(表でいうと右下の2つ)　この2つの値によって、`透過性へコントラスト`をつけ、Gooey Effect を作ります。



![ダウンロード (33).gif](https://qiita-image-store.s3.amazonaws.com/0/232715/9f34b506-e037-f28d-414f-f9db268b49c8.gif)

透過性のコントラストを増大させ、Gooey Effectができました。
<br/>
⑶ feBlend

```index.html
  <feBlend in="SourceGraphic" in2="filter" />
```

⑵でやってきたことを、SourceGraphicに合成し、完成です。



#4. SVG Filter まとめ

1. feGaussianBlur で、blur をつける
2. feColorMatrix　で、透過性のコントラストを設定する
3. feBlend で合成する。


これで、準備が完了します！！
では、涙を作っていきます。


#5. 実践


```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="css/styles.css" />
  </head>
  <body>
    <div class="container">
      <div class="gooey">
        <div class="circle"></div>
        <div class="circle"></div>
      </div>
      <svg>
        <defs>
          <filter id="filter">
            <feGaussianBlur in="SourceGraphic" stdDeviation="1" 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="filter"
            />
            <feBlend in="SourceGraphic" in2="blur" />
          </filter>
        </defs>
      </svg>
    </div>
  </body>
</html>
```

```styles.css
body {
  margin: 0;
  padding: 0;
}

.container {
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: url("https://dl.dropbox.com/s/tordfdhfhazq10s/face.png?dl=0");
  background-size: cover;
  background-position-y: -200px;
}

.gooey {
  position: relative;
  width: 500px;
  height: 500px;
  margin: 0 auto;
  filter: url("#filter");
}

.circle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 120px;
  height: 120px;
  margin: auto;
  background: #8080ff;
  border-radius: 50%;
  opacity: 1;
}

.circle:first-child {
  left: 20%;
  top: 30%;
  width: 100px;
  height: 60px;
}

.circle:nth-child(2) {
  left: 26%;
  top: 30%;
  width: 100px;
  height: 60px;
}

.circle:first-child:hover {
  animation: move1 2s linear 0.2s infinite;
}

.circle:nth-child(2):hover {
  animation: move2 1.5s linear 0.2s infinite;
}

@keyframes move1 {
  0% {
    transform: translateX(0px);
  }
  20% {
    transform: translate(-20px, 50px) scale(1.2, 2) rotateY(20deg);
  }
  50% {
    transform: translate(-20px, 100px) scale(0.6, 1.1) rotateY(30deg);
  }
  80% {
    transform: translate(-20px, 150px) scale(0.6, 1.1) rotateY(50deg);
  }
  100% {
    transform: translate(-20px, 200px) scale(0.6, 1.1) rotateY(90deg);
  }
}

@keyframes move2 {
  0% {
    transform: translateX(0px);
  }
  20% {
    transform: translate(100px, 30px) scale(1.2 0.5);
  }
  50% {
    transform: translateY(100px) scale(0.6, 0.6) rotateY(20deg);
  }
  80% {
    transform: translateY(150px) scale(0.6, 0.6) rotateY(50deg);
  }
  100% {
    transform: translateY(200px) scale(0.6, 0.6) rotateY(90deg);
  }
}
```

![ダウンロード (34).gif](https://qiita-image-store.s3.amazonaws.com/0/232715/9273f1f8-2814-997e-cba6-77a8e3713675.gif)

完成しました。
CSSの時と違って、涙の背景が白くなりません。
こんなに簡単に、SVGで Gooey Effect を作れるんですね。　

これからしばらく、このEffectを使った、ボタンなどを作って行きます。
それではまた明日！