Site icon Tips Note by TAM

SVGでリアルな湯気を作ってみる

もう7年ほど前になりますがFlashでサイト製作をしていた時代に、表現に悩まされるものがありました。

それが『湯気』です。

イラストを使った可愛い表現なら問題ないですが、リアルな感じを作ろうと思うとこれがなかなか難しい。最近では動画やアニメGIFなどで代用されていたりすることも多いと思いますが、今回はそんな素材がない時に使える 『SVGで作るリアルな湯気』 を紹介したいと思います!

See the Pen Steam by uenaka (@uenaka) on CodePen.

SVGで湯気を書く

まずはSVGで湯気の形を自由に書いてみてください。
難しく聞こえるかもしれませんが、後々ボカして使用しますので形に拘る必要はありません。
参考までに私が書いてみた湯気がこちらです。

SVGにanimateを追記して動す

よりリアルな動きに見せるため、SVGで書いた湯気を動かします。
ここも動きも細かく設定する必要はなく、ざっくり座標を書き換えてもらう程度で大丈夫だと思います。

最初SVGを開いた段階では下記のようになっている思いますが

<path fill="#FFF" d="M173.367,5〜"/>

これを書き換えてanimateタグを追記し、values属性に 動く前のパス; 動いた後のパス; 動く前のパス の順でセミコロン区切りで追記していきます。

  <path fill="#FFF" >
  <animate attributeName="d" dur="7s" repeatCount="indefinite"  
  values="M173.367,5〜動く前のパス〜;M173.36〜動いた後のパス〜;M173.367,5〜動く前のパス〜;" />

dur = アニメーションが1ループする時間(今回は7秒に設定)
repeatCount = アニメーションのリピート回数(ずっと繰り返しなので、indefiniteを設定)

CSSでぼかして動かす

SVGで大まかな動きが実装できれば、組み込みをしていきましょう。
CSSでブラー(ぼかし)エフェクト、変形などをかけつつ、下から上に湯気を動かします。
(上にあがるにつれ、ブラーが強くなり透過度も高くなるように設定)

 .steam {
        position: absolute;
        -webkit-animation: steam_Move 18s infinite linear;
        animation: steam_Move 18s infinite linear;
        transition: all 1s;
    }

    @keyframes steam_Move {
         0% {
            filter: blur(10px);
            transform: rotateY(0deg);
            transform: scale(1, 1);
            opacity: 0.75;
            top: 340px;
        }
        33% {
            transform: rotateY(40deg);
            transform: scale(0.6, 1.2);
        }
        66% {
            transform: rotateY(2deg);
            transform: scaleY(1.2, 0.4);
        }
        100% {
            filter: blur(16px);
            transform: rotateY(50deg);
            transform: scaleY(1.4, 1.2);
            opacity: 0;
            top: -600px;
        }
    }

また、湯気が1つだけだと上にあがりきった際に途切れてしまうため、時間差でもうひとつ同じ湯気を動かして、画面に交互に現れるように調整しておきます。(今回はJavaScriptのsetTimeoutで実装)

重なり順を調整

最後にマスク画像を含む重なり順を調整します。
オリジナルの画像を背景画像に指定し(図:A)、その上に湯気のSVG(図:B)、一番上にマスク用の画像を重ねるイメージです(図:C)

以上で完成となります!
良い感じの湯気が実装できましたでしょうか?
是非参考にしてみてください!