uenaka

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

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

それが『湯気』です。

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

SVGで湯気を書く

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

SVGにanimateを追記して動す

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

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

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

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

1
2
3
<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でブラー(ぼかし)エフェクト、変形などをかけつつ、下から上に湯気を動かします。
(上にあがるにつれ、ブラーが強くなり透過度も高くなるように設定)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.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)

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

お問い合わせはこちら