👩‍💻

#144 JavaScriptとCSSで簡単なアクアリウムを作ってみた

に公開

はじめに

今回は、JavaScript と CSS で簡単なアクアリウムを作成してみました。
指定した魚の画像が画面上を往復し、音楽の再生と停止も行えるようにします。

作ってみる

環境

今回はCodePenを使って作成します。
https://codepen.io/

準備

CodePenではHTML/CSS/JSファイルが用意されており、それぞれを自動で読み込んでくれます。
そのため、ファイルの作成は行いません。
また、CodePenの無料プランだと画像・音声ファイルがアップロードできないため、Dropboxを使ってファイルをアップロードし参照するようにしています。
今回は「泳がせたい魚の画像」と「水槽(背景)の画像」、「再生したい音声」のファイルが必要になります。

ファイルの内容を書き換える

HTML

html
<body>
<!-- 水槽 -->
<div id="aquarium">
    <!-- 魚 -->
    <div class="fish"></div>
    <div class="fish"></div>
    <div class="fish"></div>
</div>

<!-- 音楽の再生/停止ボタン -->
<div id="audio">
    <button onclick="toggleMusic()">音楽ON/OFF</button>
</div>
 
<audio id="relax-audio" loop>
    <source src="https://dl.dropbox.com/再生したい音声" type="audio/mp3">
</audio>

</body>

水槽(#aquarium)の中に魚(.fish)を3つ作成しました。
.fishにはCSSで動きを設定していきます。
また、#audio 内のボタンをクリックしてtoggleMusic()を呼び出します。
toggleMusic()で試用される audioタグでは音楽をループ再生するよう記述しています。

CSS

body {
    margin: 0;
    padding: 0;
}

/* 水槽 */
#aquarium {
    position: relative;
    width: 100vw;
    height: 100vh;
    overflow: hidden; /* 魚がはみ出た部分は非表示にする */
    background-image: url('https://水槽の画像');
    background-size: cover;
}

/* 魚 */
.fish {
    position: absolute;
    width: 120px;
    height: 80px;
    background-image: url('https://泳がせたい魚の画像');
    background-size: cover;
    animation: swim linear infinite; /* 動きの指定 */
}

/* 魚ごとの設定 */
.fish:nth-child(1) { 
    top: 20vh;
    animation-duration: 10s; /* 10秒で移動 */
}

.fish:nth-child(2) { 
    top: 50vh;
    animation-duration: 12s; /* 12秒で移動 */
}

.fish:nth-child(3) { 
    top: 80vh;
    animation-duration: 8s; /* 8秒で移動 */
}

/* 魚の泳ぐ動き */
@keyframes swim {
    /* 画面左側からスタート */
    0% { left: -100px; transform: scaleX(-1); } 

    /* 途中まで左向きで進む(49%の時点でまだ反転しない) */
    49% { transform: scaleX(-1); } 

    /* 画面右端(50%地点)で方向転換(進行方向に合わせて画像を反転する) */
    50% { left: 100vw; transform: scaleX(1); }

    /* そのまま画面左側へ戻る */
    100% { left: -100px; transform: scaleX(1); }
}

nth-child(n)でfishのn番目の要素にCSSが適用されます。
animation-durationでアニメーションを何秒で1往復させるか設定し、魚ごとに泳ぐ速さをバラバラにしています。

@keyframes部分では以下の設定をしています。
0%はアニメーションの始まり、100%はアニメーションの終わりを示します。
※使用する画像の向きに合わせ、scaleX()の値は変更してください!

【0%のとき】
left: -100px; → 画面の外(左側の-100px)にいる
transform: scaleX(-1); → 左向き(反転)

【49%のとき】
transform: scaleX(-1); → 左向きのまま進行

【50%のとき】
left: 100vw; → 画面の右端に到達
transform: scaleX(1); → 右向きに反転

【100%のとき】
left: -100px; → 再び左端の外へ
transform: scaleX(1); → 右向きのまま

→ ここでアニメーションがループして、永遠に泳ぎ続ける

JS

jsx
// 音楽の再生/停止の状態を管理
let isMusicPlaying = false;
const audio = document.getElementById('relax-audio');

// 音楽再生/停止の切り替え
function toggleMusic() {
    if (isMusicPlaying) {
        audio.pause();
    } else {
        audio.play();
    }
    isMusicPlaying = !isMusicPlaying;
}

const audio = document.getElementById('relax-audio'); でaudioタグを取得しています。
toggleMusic() 関数で audio.play() と audio.pause() を切り替え、再生中なら停止、停止中なら再生の動作を行います。

動かしてみる

画面表示

音楽ON/OFFのボタンをクリックすると、音声ファイルが繰り返し再生されます。
もう一度クリックで停止します。

CodePen

実際に動かせるようにしてみました。
魚の泳ぐ速さや回転の設定を変更してみてください。

最後に

今回は、JavaScriptとCSSを使ってアクアリウムを作成してみました。
CSSでも簡単なアニメーションを付けることができました。
最後までご覧いただきありがとうございました。

参考:https://zero-plus.io/media/css-animation-keyframes/

Discussion