【JavaScript】(화장실의) 음희를 만들어 보았다

안녕하세요! Qiita 최초 투고의 im90 라고 합니다. 현재 프론트 엔드 엔지니어를 목표로 공부 중입니다.

스스로 뭔가 만들어 보는 것이 제일 공부가 된다고 자주 듣기 때문에 처음으로 자작 앱을 만들어 보았습니다.
이번에는, 음희(화장실의 소리 되는 녀석)를 만들어 보았습니다.

전혀 큰 일은 하고 있지 않습니다만, 추억으로서 이쪽에 남겨 두고 싶습니다.

구현한 기능


  • 시작 버튼을 누르면 소리가 흐릅니다 (25 초)
  • 정지 버튼을 누르면 소리가 멈 춥니 다
  • 소리가 흐르는 동안 시작 버튼을 비활성화합니다
  • 정지 → 시작시 다시 25 초 동안 소리를냅니다.
  • 남은 시간 표시

  • 간단합니다
    찾았습니다만 진짜 음희의 소리가 없었기 때문에, 이번은 파도의 소리를 사용했습니다.

    소리가 나오는 데모가 없어서 죄송합니다・・・.

    코드(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)


  • 변수 정의
  • 시작 버튼을 누르면 소리가 흐르는 함수를 만들고 25 초 만에 타임 아웃합니다 (setTimeout()).
  • 정지 버튼을 누르면 소리가 멈추는 함수를 만듭니다
  • 재생시에는 스타트 버튼을 무효로 한다.
  • 정지 버튼을 눌러 재생할 때 처음부터 소리가 흐른다 ( clearTimeout() ).

  • 만들어 보자.



    실은 이번 현역 프로그래머에게 봐 주셨습니다만, 아래와 같은 어드바이스를 받았습니다.
  • onclick보다는 addEventListener를 사용하는 것이 보기 쉽다. (어떤 요소와 함수가 붙어 있는지 한눈에 알기 쉽기 때문에)
  • 현장에서는 == 보다 === 를 사용하는 것이 요구된다. 이 기사에서 알기 쉽게 설명되었습니다. JavaScript 잊어 버리는 경향 ===과 ==의 차이

  • 그리고는 var 가 아니고 letconst
    또, 스피커의 외형을 재현하는데 ・・・ 를 몇개나 썼습니다만, 보다 좋은 방법이 있는 것 같은 생각도 합니다.

    눈치채는 점이 있으면, 좀더 이러한 쪽이 좋은 등, 꼭 어드바이스 받을 수 있으면 다행입니다.

    우선 지금은 다음 앱에 도전해 보려고 합니다! 방문해 주셔서 감사합니다.

    좋은 웹페이지 즐겨찾기