LoginSignup
5
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-04

CSS animation day15 となりました。

前回、 を作りましたが、背景画像との相性が悪く、Codepen の作品が変になってしまいました。Gooey Effect をつけた背景と、background 画像が、お互いに干渉していたせいです。

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

1. 完成版

ダウンロード (34).gif

2. 参考文献

CSS trick
THE ORTHODOX WORKS
SVG1.1
codorops (かなりわかりやすいです!)

3. SVG filter を学ぶ

❶.

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

・・・

SVGでは、原始フィルターと呼ばれるものを、子要素にセットして、filter プロパティと一緒に使う必要があります。

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

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

などあります。実際のコードを見てみましょう。


⑴ 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

上の画像の変化が、feDaussianBlur の効果です。


⑵ 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 については、こちらの記事 ご一読ください。

スクリーンショット 2019-02-04 10.54.50.png

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

ダウンロード (33).gif

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


⑶ 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

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

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

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2