1.はじめに
先日、街のカフェでホットコーヒーを飲んでいたとき、「この湯気ってコードで再現できないかな?」と思ったのがきっかけで、CSSとJavaScriptだけで湯気アニメーションを作ってみました。
アニメーションって敷居が高そうに感じるかもしれませんが、今回はHTML/CSS/JavaScriptだけで実装できるので、初心者の方にもおすすめです。
2.完成デモ
以下が実際のデモです(コピペでそのまま動きます):
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>湯気アニメーション</title>
<style>
body {
background: #40342a;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.cup {
width: 120px;
height: 140px;
background: #8b5e3c;
border-radius: 0 0 60px 60px;
position: relative;
overflow: visible;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.steam-container {
position: absolute;
top: -30px;
left: 0;
width: 100%;
height: 150px;
pointer-events: none;
overflow: visible;
z-index: 1;
}
.steam {
position: absolute;
bottom: 100px;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
filter: blur(4px);
animation: floatUp 4s ease-out forwards;
opacity: 0;
z-index: 2;
}
@keyframes floatUp {
0% {
transform: translate(0, 0) scale(1);
opacity: 0.6;
}
25% {
transform: translate(-15px, -30px) scale(1.2);
opacity: 0.7;
}
50% {
transform: translate(15px, -60px) scale(1.5);
opacity: 0.5;
}
75% {
transform: translate(-10px, -90px) scale(1.7);
opacity: 0.4;
}
100% {
transform: translate(0, -130px) scale(2);
opacity: 0;
}
}
</style>
</head>
<body>
<div class="cup">
<div class="steam-container"></div>
</div>
<script>
const container = document.querySelector('.steam-container');
function createSteam() {
const steam = document.createElement('div');
steam.classList.add('steam');
const size = Math.random() * 10 + 20;
steam.style.width = `${size}px`;
steam.style.height = `${size}px`;
steam.style.left = `${Math.random() * 80 + 10}px`;
steam.style.filter = `blur(${Math.random() * 3 + 2}px)`;
container.appendChild(steam);
setTimeout(() => {
steam.remove();
}, 4000);
}
setInterval(() => {
createSteam();
if (Math.random() > 0.3) createSteam();
}, 500);
</script>
</body>
</html>
3.解説
3.1.湯気の見た目は CSS で再現
.steam {
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
filter: blur(4px);
...
}
ここでは .steam
というクラスで1つの湯気を表現しています。ぼかし効果(filter: blur()
)を加えることで、煙のように柔らかく見える白い丸を作り、それを border-radius: 50%
で完全な円形にしています。
さらに background: rgba()
を使うことで、透明度を調整し、「空気に溶け込むような」質感を出しています。
3.2.湯気の動きは @keyframes で実現
@keyframes floatUp {
0% { transform: translate(0, 0) scale(1); opacity: 0.6; }
25% { transform: translate(-15px, -30px) scale(1.2); opacity: 0.7; }
50% { transform: translate(15px, -60px) scale(1.5); opacity: 0.5; }
75% { transform: translate(-10px, -90px) scale(1.7); opacity: 0.4; }
100% { transform: translate(0, -130px) scale(2); opacity: 0; }
}
このアニメーションでは、湯気がふわふわと左右に揺れながら上昇する動きを作っています。
translate(X, Y)
:左右に揺れるようにx軸を変えながら、y軸で上昇。scale()
:上に行くほど大きく見えるように拡大。opacity
:消えていくように透明に。
この3つを組み合わせることで、自然で柔らかい湯気の動きを実現しています。
3.3.JavaScriptで湯気をランダムに生成
function createSteam() {
const steam = document.createElement('div');
steam.classList.add('steam');
const size = Math.random() * 10 + 20;
steam.style.width = `${size}px`;
steam.style.height = `${size}px`;
steam.style.left = `${Math.random() * 80 + 10}px`;
steam.style.filter = `blur(${Math.random() * 3 + 2}px)`;
container.appendChild(steam);
setTimeout(() => steam.remove(), 4000);
}
この関数は、新しい湯気の要素を1つ作って .steam-container
に追加し、4秒後に削除しています。
ポイントは:
Math.random()
を使って、湯気のサイズ・位置・ぼかし度合いを毎回変えていること。- これによって、すべての湯気が少しずつ違う見た目になり、リアルさが増しています。
- 湯気は
setInterval()
で一定間隔ごとに生成されているので、止まらずふわふわ出続けます。
setInterval(() => {
createSteam();
if (Math.random() > 0.3) createSteam(); // ランダムで2つ出ることも
}, 500);
このランダム性が、「自然に見えるアニメーション」を作る上でとても重要です。
4.まとめ
「湯気」という抽象的なものでも、CSSとJavaScriptだけでここまで再現できるのが面白かったです。
今回のポイントは:
- CSSの
blur
とopacity
を活かすことでリアルな質感を演出 @keyframes
で自然な動きを作る- JavaScriptでランダム生成して、単調にならないようにする
ちょっとした遊び心で始めたコードが、想像以上に面白いものになりました。
コメント