본문 바로가기
JAVASCRIPT

자바스크립트 게임 이펙트01 : 음악 효과

by dongjin6539 2023. 4. 27.
728x90
반응형

자바스크립트 게임 이펙트01 : 음악 효과

수업 시간에 배운 내용을 복습하면서 해보겠습니다.

코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2 / MUSIC.CSS / JS) / 완성화면

 

 

 

코드 블럭

<!-- 뮤직 플레이어 -->
    <div class="music__wrap">
        <div class="music__inner">
            <div class="music__header">
                <span class="left"></span>
                <h2>Music Player</h2>
                <span class="right"></span>
            </div>
            <div class="music__contents">
                <div class="music__view">
                    <div class="image">
                        <img src="img/music_view01.png" alt="음악">
                    </div>
                </div>
                <div class="music__control">
                    <div class="title">
                        <h3>노래 제목</h3>
                        <p>노래 작가 이름</p>
                    </div>
                    <div class="progress">
                        <div class="bar">
                            <audio id="main-audio" src="audio/music_audio01.mp3"></audio>
                        </div>
                        <div class="timer">
                            <span class="current">0:00</span>
                            <span class="duration">3:55</span>
                        </div>
                        <div class="control">
                            <span>
                                <i class="repeat" id="control-repeat" title="전체 반복"></i>
                            </span>
                            <span>
                                <i class="prev" id="control-prev" title="이전곡 재생"></i>
                            </span>
                            <span>
                                <i class="play" id="control-play" title="재생"></i>
                            </span>
                            <span>
                                <i class="next" id="control-next" title="다음곡 재생"></i>
                            </span>
                            <span>
                                <i class="list" id="control-list" title="재생 목록"></i>
                            </span>
                            <!-- <span class="repeat_one">한곡 반복</span>
                            <span class="shuffle">랜덤 반복</span>
                            <span class="stop">정지 반복</span> -->
                        </div>
                    </div>
                </div>
            </div>
            <div class="music__footer"></div>
        </div>
    </div>
<!-- // 뮤직 플레이어 -->

구성

 

CSS

 

JAVASCRIPT

const musicWrap = document.querySelector(".music__wrap");
const musicName = musicWrap.querySelector(".music__control .title h3");
const musicArtist = musicWrap.querySelector(".music__control .title p");
const musicView = musicWrap.querySelector(".music__view .image img");
const musicAudio = musicWrap.querySelector("#main-audio");
const musicPlay = musicWrap.querySelector("#control-play");
const musicPrevBtn = musicWrap.querySelector("#control-prev");
const musicNextBtn = musicWrap.querySelector("#control-next");
const musicProgress = musicWrap.querySelector(".progress");
const musicProgressBar = musicWrap.querySelector(".progress .bar");
const musicProgressCurrent = musicWrap.querySelector(".progress .timer .current");
const musicProgressDuration = musicWrap.querySelector(".progress .timer .duration");

let musicIndex = 3; // 현재 음악 인덱스

// 음악 재생
const loadMusic = (num) => {
    musicName.innerText = allMusic[num-1].name;             // 뮤직 제목
    musicArtist.innerText = allMusic[num-1].artist;         // 뮤직 아티스트
    musicView.src = `img/${allMusic[num-1].img}.png`;       // 뮤직 이미지
    musicView.alt = allMusic[num-1].name;                   // 뮤직 이미지 alt
    musicAudio.src = `audio/${allMusic[num-1].audio}.mp3`;  // 뮤직 오디오 파일
};

// 재생
const playMusic = () => {
    musicWrap.classList.add("paused");
    musicPlay.setAttribute("title", "정지");
    musicPlay.setAttribute("class", "stop");
    musicAudio.play();
};

// 정지
const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicPlay.setAttribute("title", "재생");
    musicPlay.setAttribute("class", "play");
    musicAudio.pause();
};

// 이전 곡 듣기
const prevMusic = () => {

    // 무한반복 if문
    // musicIndex--;
    // if(musicIndex == 0)musicIndex = allMusic.length;

    // 무한반복 삼항연산자
    musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;

    loadMusic(musicIndex);
    playMusic();
};

// 다음 곡 듣기
const nextMusic = () => {

    // 무한반복 if문
    // musicIndex++;
    // if(musicIndex == allMusic.length+1)musicIndex = 1;

    // 무한반복 삼항연산자
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;

    loadMusic(musicIndex); 
    playMusic();
};

// 뮤직 진행바
musicAudio.addEventListener("timeupdate", e => {
    console.log(e);
    const currentTime = e.target.currentTime;           // 현재 재생되는 시간
    const duration = e.target.duration;                 // 오디오의 총 길이
    let progressWidth = (currentTime/duration) * 100;   // 전체길이에서 현재 진행되는 시간을 백분위 단위로 나누면 현재 시간을 알 수 있음

    musicProgressBar.style.width = `${progressWidth}%`;

    // 전체 시간
    musicAudio.addEventListener("loadeddata", () => {
        let audioDuration = musicAudio.duration;
        let totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if(totalSec < 10) totalSec = `0${totalSec}`
        musicProgressDuration.innerText = `${totalMin}:${totalSec}`;
    });

    // 진행 시간
    let currentMin = Math.floor(currentTime / 60);
    let currentSec = Math.floor(currentTime % 60);
    if(currentSec < 10) currentSec = `0${currentSec}`
    musicProgressCurrent.innerText = `${currentMin}:${currentSec}`;
});

// 진행 바 클릭
musicProgress.addEventListener("click", (e) => {
    let progressWidth = musicProgress.clientWidth;  // 진행바 전체 길이
    let clickedOffsetX = e.offsetX;                   // 진행바를 기준으로 측정되는 X좌표 값
    let songDuration = musicAudio.duration;         // 오디오 전체 길이

    // 백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
    musicAudio.currentTime = (clickedOffsetX/progressWidth) * songDuration;
});
// 플레이 버튼 클릭
musicPlay.addEventListener("click", () => {
    const isMUsicPaused = musicWrap.classList.contains("paused");   // 음악 재생 중
    isMUsicPaused ? pauseMusic() : playMusic();
});

// 이전곡 버튼 클릭
musicPrevBtn.addEventListener("click", () => {
    prevMusic();
});

// 다음곡 버튼 클릭
musicNextBtn.addEventListener("click", () => {
    nextMusic();
});

window.addEventListener("load", () => {
    loadMusic(musicIndex);
});

자바스크립트 구성

  • 뮤직 플레이어에 관한 js파일 입니다.
  • 필요한 부분의 class 명을 가져와서 각각 선택자를 변수로 만들어 줍니다.
  • 다음 임시로 변수 musicIndex를 현재 재생중인 인덱스 값을 임시로 저장해줍니다.

 

음악 재생

음악 재생

  • 음악 재생 부분을 변수 loadMusic 함수를 만들고 인덱스 값을 num으로 만들어서 변수 musicIndex를 가져오게 합니다.
  • 각각 제목, 아티스트, 이미지, 이미지 alt, 오디오 파일을 가져오기 위해 음악의 파일을 배열안에 객체가 있는 형식으로 만들어서 각각의 선택자 부분에 텍스트를 넣기 위해서는 innerText를 사용하고 이미지랑 오디오 부분에는 src형식을 변경해주기 위해 src를 적고 배열안에 객체의 값을 불러옵니다.

재생, 정지

  • 재생 부분을 변수 playMusic 함수를 만들고 musicWrap 선택자에 클래스를 paused를 추가 시켜주고 musicPlay 선택자에 setAttribute를 사용해서 속성을 가져와서 텍스트를 변경시켜줍니다. 그래서 title 부분을 가져와서 정지로 변경시키고 class를 가져와서 stop으로 변경시키고 musicAudio 선택자를 play 시켜줍니다.
  • 정지 부분을 변수 pasueMusic 함수를 만들고 musicWrap 선택자에 추가된 클래스 paused를 삭제 시켜주고 musicPlay 선택자에 setAttribute를 사용해서 속성을 가져와서 텍스트를 변경시켜줍니다. 그래서 title 부분을 가져와서 재생으로 변경시키고 class를 가져와서 play으로 변경시키고 musicAudio 선택자를 pause 시켜줍니다.

이전 곡 듣기, 다음 곡 듣기

  • 이전 곡 듣기 부분을 변수 prevMusic 함수를 만들고 버튼을 누르면 이전 곡으로 가게 하기 위해 삼항연산자를 사용했습니다. 
  • 삼항연산자로 현재 진행중인 인덱스 값 변수 musicIndex의 값이 1이여서 true이면 musicIndex의 값이 음악 파일 정보가 있는 allMusic 배열의 갯수를 가져오고 false이면 변수 musicIndex의 값을 -- 연산자로 줄여줍니다. 그리고 재생 함수인 playMusic( );를 실행시켜줍니다.
  • 다음 곡 듣기 부분을 변수 nextMusic 함수를 만들고 버튼을 누르면 다음 곡으로 가게 하기 위해 삼항연산자를 사용했습니다. 
  • 삼항연산자로 현재 진행중인 인덱스 값 변수 musicIndex의 값이 allMusic 배열의 갯수일때 true이면 musicIndex의 값을 1로 가져오고 false이면 변수 musicIndex의 값을 ++ 연산자로 늘려줍니다. 그리고 재생 함수인 playMusic( );를 실행시켜줍니다.

 

뮤직 진행바

진행바 시간

  • 선택자 musicAudio에 시간의 업데이트 속성을 가져오기 위해 addEventListener("timeupdate")를 사용해줍니다.
  • 그리고 값을 가져오기 위해 e로 설정해줍니다.
  • 현재 재생되는 시간을 변수 currentTime으로 값의 target부분의 currentTime 가져옵니다.
  • 오디오의 총 길이를 변수 duration으로 값의 target부분의 duration을 가져옵니다.
  • 전체길이에서 현재 진행되는 시간을 백분위 단위로 나누면 현재 시간을 알 수 있으므로 변수 progressWidth를 만들어서 (currentTime / duration) 부분에 *100을 해줍니다.
  • 다음 선택자 musicProgressBar 부분에 스타일을 width값을 변수 progressWidth%로 변경시켜줍니다.

전체 시간

  • 선택자 musicAudio에 데이터를 가져오기 위해 addEventListener("loadeddata")를 사용해줍니다.
  • 전체 시간을 가져오기 위해 변수 audioDuration으로 선택자 musicAudio의 duration을 가져옵니다.
  • 전체 시간의 분을 가져오기 위해 변수 totalMin으로 변수 audioDuration / 60으로 나눈 몫을 가져와서 소수점을 버리기 위해 Math.floor를 사용해줍니다.
  • 전체 시간의 초를 가져오기 위해 변수 totalSec으로 변수 audioDuration % 60으로 나눈 나머지를 가져와서 소수점을 버리기 위해 Math.floor를 사용해줍니다. 그리고 초가 한자리수가 되면 앞에 0을 붙이기 위해 if문을 사용해서 변수 totalSec이 10보다 작으면 totalSec=`0${totalSec}`;으로 작성해서 앞에 0을 붙여줍니다.
  • 다음 입력될 부분의 선택자 musicProgressDuration에 innerText를 사용해서 변수 totalMin과 변수 totalSec를 입력시켜줍니다.

진행 시간

  • 현재 진행중인 분을 가져오기 위해 변수 currentMin으로 진행바 시간에서 만든 변수 currentTime / 60으로 나눈 몫을 가져와서 소수점을 버리기 위해 Math.floor를 사용해줍니다.
  • 현재 진행중인 초를 가져오기 위해 변수 currentSec으로 변수 currentTime % 60으로 나눈 나머지를 가져와서 소수점을 버리기 위해 Math.floor를 사용해줍니다. 그리고 초가 한자리수가 되면 앞에 0을 붙이기 위해 if문을 사용해서 변수 currentSec이 10보다 작으면 currentSec=`0${currentSec}`;으로 작성해서 앞에 0을 붙여줍니다.
  • 다음 입력될 부분의 선택자 musicProgressCurrent에 innerText를 사용해서 변수 currentMin과 변수 currentSec를 입력시켜줍니다.

진행바 클릭

  • 선택자 musicProgress를 클릭했을 때 속성을 주기 위해 addEventListener("click")를 사용해줍니다.
  • 그리고 값을 가져오기 위해 e로 설정해줍니다.
  • 진행바 전체 길이를 가져오기 위해 변수 progressWidth로 선택자 musicProgres.clientWidth를 사용해서 값을 가져옵니다.
  • 다음 진행바 기준으로 클릭했을 때 측정되는 x좌표의 값을 가져오기 위해 변수 clickedOffsetX로 값의 offsetX를 가져옵니다.
  • 다음 오디오 전체 길이를 자겨오기 위해 변수 songDuration으로 musicAudio의 duration을 가져옵니다.
  • 백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꾸기 위해 선택자 musicAudio의 currentTime 현재 재생중인 시간을 위의 (변수 clickedOffsetX / 변수 progressWidth) 나눈 몫에 * 변수 songDuration를 해서 값을 가져옵니다.

 

버튼 클릭
  • 플레이 버튼을 클릭했을 때 효과를 주기 위해 선택자 playMusic에 addEventListener("click")를 사용해줍니다.
  • 음악 재생 중을 확인하기 위해 변수 isMusicPaused로 선택자 musicWrap에 class가 paused가 포함되어있는지 아닌지 contains로 확인을 해줍니다.
  • 삼항연산자로 true일때 pauseMusic( ) 함수를 실행시키게 하고 false이면 playMusic( ) 함수를 실행시키게 해줍니다.
  • 이전 곡 버튼을 클릭했을 때 효과를 주기 위해 선택자 musicPrevBtn에 addEventListener("click")를 사용해주고 prevMusic( ) 함수를 실행시키게 해줍니다.
  • 다 곡 버튼을 클릭했을 때 효과를 주기 위해 선택자 musicNextBtn에 addEventListener("click")를 사용해주고 nextMusic( ) 함수를 실행시키게 해줍니다.

 

 

참고

  • 속성, 메서드
속성, 메서드 설명
addEventListener("timeupdate") 시간의 업데이트 속성을 가져와줍니다. 
addEventListener("loadeddata") 미디어의 현재 재생 위치에 있는 프레임이 로드를 완료하면 시작됩니다.
classList.contains( ) class 명이 포함되어있는지 안되어있는지 확인을 해줍니다.
728x90
반응형