5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【JavaScript】(トイレの)音姫を作ってみた

Last updated at Posted at 2019-09-23

こんにちは!Qiita初投稿のim90と申します。現在、フロントエンドエンジニアを目指して勉強中です。

自分で何か作ってみるのが一番勉強になる、とよく聞くので、初めて自作アプリを作ってみました。
今回は、音姫(トイレの音なるやつ)をつくってみました。

全然大した事はしていないのですが、思い出としてこちらに残しておきたいと思います。

#実装した機能

  • スタートボタンを押したら音が流れる(25秒)
  • ストップボタンを押したら音が止まる
  • 音が流れている間は、スタートボタンを無効にする
  • ストップ → スタートの際は、改めて25秒間音を流す
  • 残り時間を表示する

シンプルです:sweat_smile: 
探しましたが本物の音姫の音が無かったので、今回は波の音を使いました。
demo.gif
音が出るデモが無くて申し訳ないです・・・。

#コード(HTML、CSS、JavaScript)

index.html
<body>
  <div class="container">
    <div class="contents-wrapper flex-box">
      <!-- speaker -->
      <div class="left">
        ・・・・・・・・・・・
        ・・・・・・・・・・・
        ・・・・・・・・・・・
        ・・・・・・・・・・・
        ・・・・・・・・・・・
        ・・・・・・・・・・・
        ・・・・・・・・・・・
      </div>
      <!-- ↓ display -->
      <div class="right">
        <div class="btn start" onclick="start()"><audio src="sounds/wave1.mp3" loop="true"></audio>&#8680;<br>start</div>
        <div class="btn stop" onclick="stop()"><br>stop</div>
        <div class="remainingTime">残り秒数:<span class="lighting"></span></div>
      </div>
      <!-- ↑ display --> 

    <div class="description">
      <p>手をかざすと25秒水の流れる音がします。
        <br>途中でボタンを押すと延長します。
      </p>
    </div>
  </div>

  <footer>TOTO</footer>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="index.js"></script>
</body>
</html>
style.css
*{
    margin: 0 auto;
    padding: 0;
    box-sizing: border-box;
}
body {
    margin: 3rem;
    padding: 2rem;
    width: 30rem;
    height: 20rem;
    text-align: center;
    border: .5px solid lightgrey;
    box-shadow: 1rem 1rem 1rem 1rem rgba(0, 0, 0, .4);
    user-select: none;   
}
.contents-wrapper{
    padding: 1.5rem;
    height: 10rem;
}
.left{
    width: 8rem;
    float: left;
    font-size: 10px;
    padding: 0;
}
.right{
    float: right;
    width: 13rem;
    padding: 1rem 0;
}
.btn{
    height: 3rem;
    width: 6rem;
    margin-bottom: 1rem;
    box-shadow: .1rem .1rem .1rem .1rem rgba(0, 0, 0, .4); 
    cursor: pointer;  
}
.btn:active{
    box-shadow: none;   
}
.start{
    float: left;
    background-color: black;
    color: whitesmoke;
}
.disabled{
    background-color: rgba(0, 0, 0, .8);
    pointer-events: none;
}
.stop{
    border: 1px solid lightgray;
    float: right;
}
.remainingTime{
    clear: both;
    text-align: left;
    font-size: 14px;
}
.description{
    clear: both;
}
footer{
    margin-top: 3.5rem;
}
index.js
var startButton = document.querySelector('.start');
var stopButton = document.querySelector('.stop');
var light = document.querySelector('.lighting');
var audio = new Audio('sounds/wave1.mp3');
audio.loop = true;
var timeoutID;
var playing = true;

//スタートボタンを押したら音を流す
function start(){
    audio.play();
    playing = true;
    light.innerHTML = 25;
    startButton.classList.add("disabled");

    var totalTime = 25000; // 25sec
    var oldTime = Date.now();

    var timerID = setInterval(function(){        
        var currentTime = Date.now();
        var diff = currentTime - oldTime;

        var remainMsec = totalTime - diff;
        var remainSec = Math.ceil(remainMsec / 1000);
        light.innerHTML = remainSec;

        if(remainSec <= 0){
            clearInterval(timerID);
            light.innerHTML = "";
            startButton.classList.remove("disabled");
        }
        if(playing === false){
            clearInterval(timerID);
            light.innerHTML = "";
        }
    }, 1000);
    timeoutID = window.setTimeout(() => {
        audio.pause();
        audio.currentTime = 0;
    }, 25000);
}

//ストップボタンを押したら音をストップさせる
function stop(){
    audio.pause();
    clearTimeout(timeoutID);
    audio.currentTime = 0;
    playing = false;
    startButton.classList.remove("disabled");
}

#作成フロー(JavaScript)

  1. 変数の定義
  2. スタートボタンを押すと音が流れる関数をつくり、25秒でタイムアウトするようにする(setTimeout())
  3. ストップボタンを押すと音が止まる関数をつくる
  4. 再生時はスタートボタンを無効にする(このままだとスタート関数が重複して実行できてしまうため)
  5. ストップボタンを押して再生したときに、最初から音が流れる(clearTimeout())この作業をしないと、ストップ → 再生したときに音が中途半端に切れてしまいました。

#作ってみて
実は今回現役プログラマーの方に見て頂いたのですが、下記のアドバイスを頂きました。

  • onclickよりかは、addEventListenerを使った方が見やすい。(どの要素と関数が紐付いているかが一目で分かりやすいため)
  • 現場では==よりも===を使う事が求められる。こちらの記事で分かりやすく説明されていました。JavaScript 忘れがちな === と == の違い

あとは、varでなくletconstに書き直せば良かったな~、と今更ながら思いました・・・:sweat:

また、スピーカーの見た目を再現するのに・・・を何個も書いたのですが、もっと良い方法があるような気もします。

お気づきの点がございましたら、もっとこうした方が良いなど、ぜひアドバイス頂けますと幸いです。

とりあえず今は次のアプリに挑戦してみようと思います!ご覧頂き、ありがとうございました。

5
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?