예제/게임 이펙트

게임 이펙트03_ 뮤직 리스트 생성

아라라_ 2023. 5. 3. 23:06

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

Frederick Philips Brooks
Mythical Man-Month 저자
728x90

오늘은 뮤직 리스트 부분을 추가하였습니다.

 

수정한 부분

const musicRepeat = musicWrap.querySelector("#control-repeat");
const musicListBtn = musicWrap.querySelector("#control-list");
const musicList = musicWrap.querySelector(".music__list");
const musicListUl = musicWrap.querySelector(".music__list ul");
const musicListClose = musicWrap.querySelector(".music__list h3 .close");

// 이전곡 듣기
const prevMusic = () => {
    musicIndex == 0 ? musicIndex = allMusic.length : musicIndex--;

    loadMusic(musicIndex);
    playMusic();
    playListMusic();

}

// 다음곡 듣기
const nextMusic = () => {
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;

    loadMusic(musicIndex);
    playMusic();
    playListMusic();

}
// 반복버튼
musicRepeat.addEventListener("click", ()=>{
    let getAttr = musicRepeat.getAttribute("class");

    switch(getAttr){
        case "repeat" :
            musicRepeat.setAttribute("class","repeat_one");
            musicRepeat.setAttribute("title","한곡 재생");
        break;
        case "repeat_one" :
            musicRepeat.setAttribute("class","shuffle");
            musicRepeat.setAttribute("title","랜덤 재생");
        break;
        case "shuffle" :
            musicRepeat.setAttribute("class","repeat");
            musicRepeat.setAttribute("title","전체 반복");
        break;
    }
})

// 오디오가 끝나면
musicAudio.addEventListener("ended", () => {
    let getAttr = musicRepeat.getAttribute("class");

    switch(getAttr){
        case "repeat" : 
            nextMusic();
        break;
        case "repeat_one" : 
            playMusic();
        break;
        case "shuffle" : 
            let randomIndex = Math.floor(Math.random() * allMusic.length +1); //랜덤 인덱스 생성

            // if(randomIndex == musicIndex){
            //     randomIndex = Math.floor(math.random() * allMusic.length +1);
            // }

            do {
                randomIndex = Math.floor(Math.random() * allMusic.length +1);
            } while (randomIndex == musicIndex);

            musicIndex = randomIndex;
            loadMusic(musicIndex);
            playMusic();
        break;
    }
    playListMusic();
})
// 플레이 버튼 클릭
musicPlay.addEventListener("click",() =>{
    const isMusicPaused = musicWrap.classList.contains("paused"); //음악 재생중
@@ -153,12 +212,85 @@ musicPlay.addEventListener("click",() =>{
// 이전곡 버튼 클릭
musicPrevBtn.addEventListener("click",() =>{
    prevMusic();
})
});

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

// 뮤직 리스트 버튼
musicListBtn.addEventListener("click", () => {
    musicList.classList.add("show");
});

musicListClose.addEventListener("click", () => {
    musicList.classList.remove("show");
});

// 뮤직 리스트 구현하기
for (let i=0; i<allMusic.length; i++){
    let li =`
        <li data-index="${i+1}">
            <span class="img">
                <img class="img" src="img/${allMusic[i].img}.png" alt="${allMusic[i].name}">
            </span>
            <span class="title">
                <strong>${allMusic[i].name}</strong>
                <em>${allMusic[i].artist}</em>
                <audio class="${allMusic[i].audio}" src="audio/${allMusic[i].audio}.mp3"></audio>
            </span>
            <span class="audio-duration" id="${allMusic[i].audio}">3:04</span>
        </li>
    `;
    // musicListUl.innerHTML += li;
    musicListUl.insertAdjacentHTML("beforeend",li);

    let liAudioDuration = musicListUl.querySelector(`#${allMusic[i].audio}`);   // 리스트에서 시간을 표시할 선택자를 가져옴
    let liAudio = musicListUl.querySelector(`.${allMusic[i].audio}`);           // 리스트에서 오디오 파일 선택
    liAudio.addEventListener("loadeddata", () => {
        let audioDuration = liAudio.duration;
        // console.log(audioDuration)
        let totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if(totalSec < 10) totalSec = `0${totalSec}`;
        liAudioDuration.innerText = `${totalMin}:${totalSec}`;
        liAudioDuration.setAttribute("data-duration",`${totalMin}:${totalSec}`);
    })
}
// 뮤직 리스트를 클릭하면 재생
function playListMusic(){
    const musicListAll = musicListUl.querySelectorAll("li");    // 뮤직 리스트 목록
    for(let i=0; i<musicListAll.length; i++){
        let audioTag = musicListAll[i].querySelector(".audio-duration");

        musicListAll[i].setAttribute("onclick","clicked(this)")

        if(musicListAll[i].classList.contains("playing")){
            musicListAll[i].classList.remove("playing");
            let dataAudioDuration = audioTag.getAttribute("data-duration");
            audioTag.innerText = dataAudioDuration;
        }

        if(musicListAll[i].getAttribute("data-index") == musicIndex){
            musicListAll[i].classList.add("playing");
            audioTag.innerText = "재생중";

        }
    }
};
playListMusic();

// 뮤직리스트를 클릭하면
function clicked(el){
    let getIndex = el.getAttribute("data-index");
    // alert(getIndex);
    musicIndex = getIndex;
    loadMusic(musicIndex);
    playMusic();
    playListMusic();

}
  • querySelector를 사용하여 DOM 요소를 선택합니다. querySelector를 사용하면 CSS 선택자를 사용하여 DOM 요소를 선택할 수 있습니다. 선택한 요소는 const 키워드를 사용하여 상수에 할당됩니다.
  • 이 코드에서는 음악 플레이어에서 사용하는 여러 가지 기능을 구현하는 함수가 정의되어 있습니다. prevMusic 함수는 이전 곡을 재생하는 기능을, nextMusic 함수는 다음 곡을 재생하는 기능을 구현합니다. playListMusic 함수는 뮤직 리스트에서 곡을 선택하여 재생하는 기능을 구현합니다.
  • 또한, 이 코드는 addEventListener 메서드를 사용하여 이벤트를 처리하는 방법을 보여줍니다. 이벤트가 발생하면 해당 이벤트 처리기 함수가 호출됩니다.
  • 이 코드에서는 switch문을 사용하여 musicRepeat 요소의 클래스 이름에 따라 다른 동작을 하도록 구현되어 있습니다. ended 이벤트 핸들러는 음악이 끝날 때 호출되며, playListMusic 함수를 호출하여 다음 곡을 재생합니다.
  • 마지막으로, for문을 사용하여 뮤직 리스트를 구현합니다. insertAdjacentHTML 메서드를 사용하여 HTML 요소를 동적으로 생성합니다. loadeddata 이벤트를 사용하여 오디오 파일의 길이를 계산하여 뮤직 리스트에 표시합니다. setAttribute 메서드를 사용하여 데이터 속성을 추가합니다. 마지막으로 querySelectorAll 메서드를 사용하여 모든 뮤직 리스트 요소에 대한 참조를 얻은 후, setAttribute를 사용하여 각 요소에 클릭 이벤트 핸들러를 추가합니다.